feat: P1-P3 全栈集成 — 数据库基础 + DWS 扩展 + 小程序鉴权 + 工程化体系
## P1 数据库基础 - zqyy_app: 创建 auth/biz schema、FDW 连接 etl_feiqiu - etl_feiqiu: 创建 app schema RLS 视图、商品库存预警表 - 清理 assistant_abolish 残留数据 ## P2 ETL/DWS 扩展 - 新增 DWS 助教订单贡献度表 (dws.assistant_order_contribution) - 新增 assistant_order_contribution_task 任务及 RLS 视图 - member_consumption 增加充值字段、assistant_daily 增加处罚字段 - 更新 ODS/DWD/DWS 任务文档及业务规则文档 - 更新 consistency_checker、flow_runner、task_registry 等核心模块 ## P3 小程序鉴权系统 - 新增 xcx_auth 路由/schema(微信登录 + JWT) - 新增 wechat/role/matching/application 服务层 - zqyy_app 鉴权表迁移 + 角色权限种子数据 - auth/dependencies.py 支持小程序 JWT 鉴权 ## 文档与审计 - 新增 DOCUMENTATION-MAP 文档导航 - 新增 7 份 BD_Manual 数据库变更文档 - 更新 DDL 基线快照(etl_feiqiu 6 schema + zqyy_app auth) - 新增全栈集成审计记录、部署检查清单更新 - 新增 BACKLOG 路线图、FDW→Core 迁移计划 ## Kiro 工程化 - 新增 5 个 Spec(P1/P2/P3/全栈集成/核心业务) - 新增审计自动化脚本(agent_on_stop/build_audit_context/compliance_prescan) - 新增 6 个 Hook(合规检查/会话日志/提交审计等) - 新增 doc-map steering 文件 ## 运维与测试 - 新增 ops 脚本:迁移验证/API 健康检查/ETL 监控/集成报告 - 新增属性测试:test_dws_contribution / test_auth_system - 清理过期 export 报告文件 - 更新 .gitignore 排除规则
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
-- =============================================================================
|
||||
-- 迁移脚本:扩展助教日度业绩明细表 — 新增定档折算惩罚字段
|
||||
-- 日期:2025-02-24
|
||||
-- 说明:在 dws.dws_assistant_daily_detail 中新增 penalty_minutes、penalty_reason、
|
||||
-- is_exempt、per_hour_contribution 四个字段,支撑定档折算惩罚检测与计算。
|
||||
-- 需求:5.1, 5.2
|
||||
-- =============================================================================
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 1. ALTER TABLE:新增定档折算惩罚字段
|
||||
-- ---------------------------------------------------------------------------
|
||||
ALTER TABLE dws.dws_assistant_daily_detail
|
||||
ADD COLUMN IF NOT EXISTS penalty_minutes NUMERIC(10,2) DEFAULT 0,
|
||||
ADD COLUMN IF NOT EXISTS penalty_reason TEXT,
|
||||
ADD COLUMN IF NOT EXISTS is_exempt BOOLEAN DEFAULT FALSE,
|
||||
ADD COLUMN IF NOT EXISTS per_hour_contribution NUMERIC(14,2);
|
||||
|
||||
COMMENT ON COLUMN dws.dws_assistant_daily_detail.penalty_minutes
|
||||
IS '定档折算惩罚分钟数,无惩罚时为 0';
|
||||
COMMENT ON COLUMN dws.dws_assistant_daily_detail.penalty_reason
|
||||
IS '惩罚原因描述,无惩罚时为 NULL';
|
||||
COMMENT ON COLUMN dws.dws_assistant_daily_detail.is_exempt
|
||||
IS '是否豁免惩罚,TRUE 时跳过惩罚计算';
|
||||
COMMENT ON COLUMN dws.dws_assistant_daily_detail.per_hour_contribution
|
||||
IS '单人每小时贡献流水 = 台费每小时实收单价 / 本次基础课助教人数';
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- =============================================================================
|
||||
-- 回滚脚本(如需撤销)
|
||||
-- =============================================================================
|
||||
-- ALTER TABLE dws.dws_assistant_daily_detail
|
||||
-- DROP COLUMN IF EXISTS penalty_minutes,
|
||||
-- DROP COLUMN IF EXISTS penalty_reason,
|
||||
-- DROP COLUMN IF EXISTS is_exempt,
|
||||
-- DROP COLUMN IF EXISTS per_hour_contribution;
|
||||
|
||||
-- =============================================================================
|
||||
-- 验证 SQL
|
||||
-- =============================================================================
|
||||
-- 1. 确认新增字段存在
|
||||
-- SELECT column_name, data_type, column_default
|
||||
-- FROM information_schema.columns
|
||||
-- WHERE table_schema = 'dws'
|
||||
-- AND table_name = 'dws_assistant_daily_detail'
|
||||
-- AND column_name IN ('penalty_minutes', 'penalty_reason', 'is_exempt', 'per_hour_contribution')
|
||||
-- ORDER BY column_name;
|
||||
-- 预期:4 行
|
||||
|
||||
-- 2. 确认字段类型正确
|
||||
-- SELECT column_name, data_type, numeric_precision, numeric_scale
|
||||
-- FROM information_schema.columns
|
||||
-- WHERE table_schema = 'dws'
|
||||
-- AND table_name = 'dws_assistant_daily_detail'
|
||||
-- AND column_name IN ('penalty_minutes', 'per_hour_contribution')
|
||||
-- ORDER BY column_name;
|
||||
-- 预期:penalty_minutes → numeric(10,2),per_hour_contribution → numeric(14,2)
|
||||
|
||||
-- 3. 确认 is_exempt 默认值
|
||||
-- SELECT column_name, column_default
|
||||
-- FROM information_schema.columns
|
||||
-- WHERE table_schema = 'dws'
|
||||
-- AND table_name = 'dws_assistant_daily_detail'
|
||||
-- AND column_name = 'is_exempt';
|
||||
-- 预期:column_default = 'false'
|
||||
@@ -0,0 +1,89 @@
|
||||
-- =============================================================================
|
||||
-- 迁移脚本:扩展会员消费汇总表 — 新增充值窗口和次均消费字段
|
||||
-- 日期:2025-02-24
|
||||
-- 说明:在 dws.dws_member_consumption_summary 中新增 30/60/90 天充值次数、
|
||||
-- 充值金额以及次均消费额度字段,支撑小程序客户看板展示。
|
||||
-- 需求:3.1, 3.2
|
||||
-- =============================================================================
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 1. ALTER TABLE:新增充值窗口 + 次均消费字段
|
||||
-- ---------------------------------------------------------------------------
|
||||
ALTER TABLE dws.dws_member_consumption_summary
|
||||
ADD COLUMN IF NOT EXISTS recharge_count_30d INTEGER DEFAULT 0,
|
||||
ADD COLUMN IF NOT EXISTS recharge_count_60d INTEGER DEFAULT 0,
|
||||
ADD COLUMN IF NOT EXISTS recharge_count_90d INTEGER DEFAULT 0,
|
||||
ADD COLUMN IF NOT EXISTS recharge_amount_30d NUMERIC(14,2) DEFAULT 0,
|
||||
ADD COLUMN IF NOT EXISTS recharge_amount_60d NUMERIC(14,2) DEFAULT 0,
|
||||
ADD COLUMN IF NOT EXISTS recharge_amount_90d NUMERIC(14,2) DEFAULT 0,
|
||||
ADD COLUMN IF NOT EXISTS avg_ticket_amount NUMERIC(14,2) DEFAULT 0;
|
||||
|
||||
COMMENT ON COLUMN dws.dws_member_consumption_summary.recharge_count_30d
|
||||
IS '近 30 天充值次数';
|
||||
COMMENT ON COLUMN dws.dws_member_consumption_summary.recharge_count_60d
|
||||
IS '近 60 天充值次数';
|
||||
COMMENT ON COLUMN dws.dws_member_consumption_summary.recharge_count_90d
|
||||
IS '近 90 天充值次数';
|
||||
COMMENT ON COLUMN dws.dws_member_consumption_summary.recharge_amount_30d
|
||||
IS '近 30 天充值金额';
|
||||
COMMENT ON COLUMN dws.dws_member_consumption_summary.recharge_amount_60d
|
||||
IS '近 60 天充值金额';
|
||||
COMMENT ON COLUMN dws.dws_member_consumption_summary.recharge_amount_90d
|
||||
IS '近 90 天充值金额';
|
||||
COMMENT ON COLUMN dws.dws_member_consumption_summary.avg_ticket_amount
|
||||
IS '次均消费额度 = total_consume_amount / MAX(total_visit_count, 1)';
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- =============================================================================
|
||||
-- 回滚脚本(如需撤销)
|
||||
-- =============================================================================
|
||||
-- ALTER TABLE dws.dws_member_consumption_summary
|
||||
-- DROP COLUMN IF EXISTS recharge_count_30d,
|
||||
-- DROP COLUMN IF EXISTS recharge_count_60d,
|
||||
-- DROP COLUMN IF EXISTS recharge_count_90d,
|
||||
-- DROP COLUMN IF EXISTS recharge_amount_30d,
|
||||
-- DROP COLUMN IF EXISTS recharge_amount_60d,
|
||||
-- DROP COLUMN IF EXISTS recharge_amount_90d,
|
||||
-- DROP COLUMN IF EXISTS avg_ticket_amount;
|
||||
|
||||
-- =============================================================================
|
||||
-- 验证 SQL
|
||||
-- =============================================================================
|
||||
-- 1. 确认新增字段存在
|
||||
-- SELECT column_name, data_type, column_default
|
||||
-- FROM information_schema.columns
|
||||
-- WHERE table_schema = 'dws'
|
||||
-- AND table_name = 'dws_member_consumption_summary'
|
||||
-- AND column_name IN (
|
||||
-- 'recharge_count_30d', 'recharge_count_60d', 'recharge_count_90d',
|
||||
-- 'recharge_amount_30d', 'recharge_amount_60d', 'recharge_amount_90d',
|
||||
-- 'avg_ticket_amount'
|
||||
-- )
|
||||
-- ORDER BY column_name;
|
||||
-- 预期:7 行
|
||||
|
||||
-- 2. 确认字段类型正确
|
||||
-- SELECT column_name, data_type, numeric_precision, numeric_scale
|
||||
-- FROM information_schema.columns
|
||||
-- WHERE table_schema = 'dws'
|
||||
-- AND table_name = 'dws_member_consumption_summary'
|
||||
-- AND column_name LIKE 'recharge_amount%'
|
||||
-- ORDER BY column_name;
|
||||
-- 预期:3 行,data_type = numeric, precision = 14, scale = 2
|
||||
|
||||
-- 3. 确认注释已设置
|
||||
-- SELECT c.column_name,
|
||||
-- pgd.description
|
||||
-- FROM information_schema.columns c
|
||||
-- JOIN pg_catalog.pg_statio_all_tables st
|
||||
-- ON c.table_schema = st.schemaname AND c.table_name = st.relname
|
||||
-- JOIN pg_catalog.pg_description pgd
|
||||
-- ON pgd.objoid = st.relid AND pgd.objsubid = c.ordinal_position
|
||||
-- WHERE c.table_schema = 'dws'
|
||||
-- AND c.table_name = 'dws_member_consumption_summary'
|
||||
-- AND c.column_name LIKE 'recharge%'
|
||||
-- ORDER BY c.column_name;
|
||||
-- 预期:6 行,description 非空
|
||||
@@ -0,0 +1,89 @@
|
||||
-- =============================================================================
|
||||
-- 迁移脚本:创建助教订单流水四项统计表
|
||||
-- 日期:2025-02-24
|
||||
-- 说明:新建 dws.dws_assistant_order_contribution 表,存储每名助教每日的
|
||||
-- 订单总流水、订单净流水、时效贡献流水、时效净贡献四项统计数据。
|
||||
-- 需求:1.1, 1.2, 1.3, 1.4, 1.5
|
||||
-- =============================================================================
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 1. 建表:dws.dws_assistant_order_contribution
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS dws.dws_assistant_order_contribution (
|
||||
contribution_id BIGSERIAL PRIMARY KEY,
|
||||
site_id INTEGER NOT NULL,
|
||||
tenant_id INTEGER NOT NULL,
|
||||
assistant_id BIGINT NOT NULL,
|
||||
assistant_nickname VARCHAR(100),
|
||||
stat_date DATE NOT NULL,
|
||||
|
||||
-- 四项统计
|
||||
order_gross_revenue NUMERIC(14,2) DEFAULT 0, -- 订单总流水
|
||||
order_net_revenue NUMERIC(14,2) DEFAULT 0, -- 订单净流水
|
||||
time_weighted_revenue NUMERIC(14,2) DEFAULT 0, -- 时效贡献流水
|
||||
time_weighted_net_revenue NUMERIC(14,2) DEFAULT 0, -- 时效净贡献
|
||||
|
||||
-- 辅助字段
|
||||
order_count INTEGER DEFAULT 0, -- 参与订单数
|
||||
total_service_seconds INTEGER DEFAULT 0, -- 总服务时长(秒)
|
||||
|
||||
-- 元数据
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
COMMENT ON TABLE dws.dws_assistant_order_contribution
|
||||
IS '助教订单流水四项统计表,粒度 (site_id, assistant_id, stat_date)';
|
||||
|
||||
COMMENT ON COLUMN dws.dws_assistant_order_contribution.order_gross_revenue
|
||||
IS '订单总流水 = 台费 + 酒水食品 + 所有助教服务费';
|
||||
COMMENT ON COLUMN dws.dws_assistant_order_contribution.order_net_revenue
|
||||
IS '订单净流水 = 订单总流水 - 所有助教服务分成';
|
||||
COMMENT ON COLUMN dws.dws_assistant_order_contribution.time_weighted_revenue
|
||||
IS '时效贡献流水 = 台费按时长分摊 + 个人服务费 + 酒水食品按时长比例';
|
||||
COMMENT ON COLUMN dws.dws_assistant_order_contribution.time_weighted_net_revenue
|
||||
IS '时效净贡献 = 时效贡献流水 - 个人服务分成';
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 2. 唯一索引:确保 (site_id, assistant_id, stat_date) 唯一
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_aoc_site_assistant_date
|
||||
ON dws.dws_assistant_order_contribution (site_id, assistant_id, stat_date);
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 3. 查询索引:按门店+日期查询
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE INDEX IF NOT EXISTS idx_aoc_stat_date
|
||||
ON dws.dws_assistant_order_contribution (site_id, stat_date);
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- =============================================================================
|
||||
-- 回滚脚本(如需撤销)
|
||||
-- =============================================================================
|
||||
-- DROP INDEX IF EXISTS dws.idx_aoc_stat_date;
|
||||
-- DROP INDEX IF EXISTS dws.idx_aoc_site_assistant_date;
|
||||
-- DROP TABLE IF EXISTS dws.dws_assistant_order_contribution;
|
||||
|
||||
-- =============================================================================
|
||||
-- 验证 SQL
|
||||
-- =============================================================================
|
||||
-- 1. 确认表存在
|
||||
-- SELECT table_schema, table_name FROM information_schema.tables
|
||||
-- WHERE table_schema = 'dws' AND table_name = 'dws_assistant_order_contribution';
|
||||
-- 预期:1 行
|
||||
|
||||
-- 2. 确认字段完整
|
||||
-- SELECT column_name, data_type, column_default
|
||||
-- FROM information_schema.columns
|
||||
-- WHERE table_schema = 'dws' AND table_name = 'dws_assistant_order_contribution'
|
||||
-- ORDER BY ordinal_position;
|
||||
-- 预期:16 行
|
||||
|
||||
-- 3. 确认索引存在
|
||||
-- SELECT indexname FROM pg_indexes
|
||||
-- WHERE schemaname = 'dws' AND tablename = 'dws_assistant_order_contribution'
|
||||
-- ORDER BY indexname;
|
||||
-- 预期:3 行(PK + idx_aoc_site_assistant_date + idx_aoc_stat_date)
|
||||
@@ -0,0 +1,34 @@
|
||||
-- =============================================================================
|
||||
-- RLS 视图:助教订单流水统计 + 已有视图重建(包含新增字段)
|
||||
-- 目标库:test_etl_feiqiu(测试)/ etl_feiqiu(生产)
|
||||
-- 前提:dws.dws_assistant_order_contribution 表已创建;
|
||||
-- dws.dws_member_consumption_summary 已新增充值窗口字段;
|
||||
-- dws.dws_assistant_daily_detail 已新增惩罚字段
|
||||
-- =============================================================================
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- 1. 新建:助教订单流水统计 RLS 视图
|
||||
-- -----------------------------------------------------------------------------
|
||||
CREATE OR REPLACE VIEW app.v_dws_assistant_order_contribution AS
|
||||
SELECT * FROM dws.dws_assistant_order_contribution
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
GRANT SELECT ON app.v_dws_assistant_order_contribution TO app_reader;
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- 2. 重建已有视图(使用 SELECT * 以包含新增字段)
|
||||
-- 原视图使用显式字段列表,新增字段不会自动暴露
|
||||
-- -----------------------------------------------------------------------------
|
||||
CREATE OR REPLACE VIEW app.v_dws_member_consumption_summary AS
|
||||
SELECT * FROM dws.dws_member_consumption_summary
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_assistant_daily_detail AS
|
||||
SELECT * FROM dws.dws_assistant_daily_detail
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
-- =============================================================================
|
||||
-- 回滚脚本
|
||||
-- =============================================================================
|
||||
-- DROP VIEW IF EXISTS app.v_dws_assistant_order_contribution;
|
||||
-- 对于已有视图的回滚,需要用旧的显式字段列表重建(参见 2026-02-24__p1_create_app_schema_rls_views.sql)
|
||||
@@ -0,0 +1,78 @@
|
||||
-- 迁移:新增 goodsStockWarningInfo 嵌套字段到 ODS 和 DWD
|
||||
-- 日期:2026-02-24
|
||||
-- 关联:一致性检查报告发现 API 独有字段 goodsStockWarningInfo 未映射
|
||||
-- 字段来源:API store_goods_master -> goodsStockWarningInfo 嵌套对象
|
||||
-- - sales_day: 销售天数(用于库存预警计算)
|
||||
-- - warning_day_max: 预警天数上限
|
||||
-- - warning_day_min: 预警天数下限
|
||||
-- - site_goods_id / tenant_goods_id: 已有冗余字段,不重复收录
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- =============================================================================
|
||||
-- 1. ODS 层:ods.store_goods_master 新增 3 列
|
||||
-- =============================================================================
|
||||
ALTER TABLE ods.store_goods_master
|
||||
ADD COLUMN IF NOT EXISTS warning_sales_day NUMERIC(18,2),
|
||||
ADD COLUMN IF NOT EXISTS warning_day_max INTEGER,
|
||||
ADD COLUMN IF NOT EXISTS warning_day_min INTEGER;
|
||||
|
||||
COMMENT ON COLUMN ods.store_goods_master.warning_sales_day IS
|
||||
'【说明】库存预警参考的日均销量。 【ODS来源】store_goods_master - goodsStockWarningInfo.sales_day。 【JSON字段】store_goods_master.json - data.orderGoodsList - goodsStockWarningInfo.sales_day。';
|
||||
COMMENT ON COLUMN ods.store_goods_master.warning_day_max IS
|
||||
'【说明】库存预警天数上限。 【ODS来源】store_goods_master - goodsStockWarningInfo.warning_day_max。 【JSON字段】store_goods_master.json - data.orderGoodsList - goodsStockWarningInfo.warning_day_max。';
|
||||
COMMENT ON COLUMN ods.store_goods_master.warning_day_min IS
|
||||
'【说明】库存预警天数下限。 【ODS来源】store_goods_master - goodsStockWarningInfo.warning_day_min。 【JSON字段】store_goods_master.json - data.orderGoodsList - goodsStockWarningInfo.warning_day_min。';
|
||||
|
||||
-- =============================================================================
|
||||
-- 2. DWD 层:dwd.dim_store_goods_ex 新增 3 列
|
||||
-- =============================================================================
|
||||
ALTER TABLE dwd.dim_store_goods_ex
|
||||
ADD COLUMN IF NOT EXISTS warning_sales_day NUMERIC(18,2),
|
||||
ADD COLUMN IF NOT EXISTS warning_day_max INTEGER,
|
||||
ADD COLUMN IF NOT EXISTS warning_day_min INTEGER;
|
||||
|
||||
COMMENT ON COLUMN dwd.dim_store_goods_ex.warning_sales_day IS
|
||||
'【说明】库存预警参考的日均销量。 【ODS来源】store_goods_master - goodsStockWarningInfo.sales_day。 【JSON字段】store_goods_master.json - data.orderGoodsList - goodsStockWarningInfo.sales_day。';
|
||||
COMMENT ON COLUMN dwd.dim_store_goods_ex.warning_day_max IS
|
||||
'【说明】库存预警天数上限。 【ODS来源】store_goods_master - goodsStockWarningInfo.warning_day_max。 【JSON字段】store_goods_master.json - data.orderGoodsList - goodsStockWarningInfo.warning_day_max。';
|
||||
COMMENT ON COLUMN dwd.dim_store_goods_ex.warning_day_min IS
|
||||
'【说明】库存预警天数下限。 【ODS来源】store_goods_master - goodsStockWarningInfo.warning_day_min。 【JSON字段】store_goods_master.json - data.orderGoodsList - goodsStockWarningInfo.warning_day_min。';
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- =============================================================================
|
||||
-- 回滚策略
|
||||
-- =============================================================================
|
||||
-- ALTER TABLE ods.store_goods_master
|
||||
-- DROP COLUMN IF EXISTS warning_sales_day,
|
||||
-- DROP COLUMN IF EXISTS warning_day_max,
|
||||
-- DROP COLUMN IF EXISTS warning_day_min;
|
||||
-- ALTER TABLE dwd.dim_store_goods_ex
|
||||
-- DROP COLUMN IF EXISTS warning_sales_day,
|
||||
-- DROP COLUMN IF EXISTS warning_day_max,
|
||||
-- DROP COLUMN IF EXISTS warning_day_min;
|
||||
|
||||
-- =============================================================================
|
||||
-- 验证 SQL
|
||||
-- =============================================================================
|
||||
-- 1. 确认 ODS 新列存在
|
||||
-- SELECT column_name, data_type FROM information_schema.columns
|
||||
-- WHERE table_schema = 'ods' AND table_name = 'store_goods_master'
|
||||
-- AND column_name IN ('warning_sales_day', 'warning_day_max', 'warning_day_min')
|
||||
-- ORDER BY column_name;
|
||||
-- 预期:3 行
|
||||
|
||||
-- 2. 确认 DWD 新列存在
|
||||
-- SELECT column_name, data_type FROM information_schema.columns
|
||||
-- WHERE table_schema = 'dwd' AND table_name = 'dim_store_goods_ex'
|
||||
-- AND column_name IN ('warning_sales_day', 'warning_day_max', 'warning_day_min')
|
||||
-- ORDER BY column_name;
|
||||
-- 预期:3 行
|
||||
|
||||
-- 3. 确认注释已设置
|
||||
-- SELECT col_description(
|
||||
-- (SELECT oid FROM pg_class WHERE relname = 'store_goods_master' AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'ods')),
|
||||
-- (SELECT ordinal_position FROM information_schema.columns WHERE table_schema = 'ods' AND table_name = 'store_goods_master' AND column_name = 'warning_sales_day')
|
||||
-- );
|
||||
-- 预期:非空
|
||||
@@ -0,0 +1,21 @@
|
||||
-- 迁移:清理 ODS_ASSISTANT_ABOLISH 残留元数据
|
||||
-- 日期:2026-02-24
|
||||
-- 关联:联调报告发现 meta.etl_task 中仍有 ODS_ASSISTANT_ABOLISH 注册,
|
||||
-- 导致调度器尝试执行已删除的任务并报 ValueError
|
||||
-- 幂等:DELETE WHERE 不存在时无影响
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- 1. 清理 meta.etl_task 中的 ODS_ASSISTANT_ABOLISH 注册
|
||||
DELETE FROM meta.etl_task WHERE task_code = 'ODS_ASSISTANT_ABOLISH';
|
||||
|
||||
-- 2. 清理 meta.etl_task 中的旧式 ASSISTANT_ABOLISH 注册(seed_scheduler_tasks.sql 残留)
|
||||
DELETE FROM meta.etl_task WHERE task_code = 'ASSISTANT_ABOLISH';
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- =============================================================================
|
||||
-- 验证 SQL
|
||||
-- =============================================================================
|
||||
-- SELECT * FROM meta.etl_task WHERE task_code IN ('ODS_ASSISTANT_ABOLISH', 'ASSISTANT_ABOLISH');
|
||||
-- 预期:0 行
|
||||
@@ -0,0 +1,196 @@
|
||||
-- =============================================================================
|
||||
-- 迁移脚本:创建 app Schema、RLS 视图层与 app_reader 角色
|
||||
-- 日期:2026-02-24
|
||||
-- 目标库:test_etl_feiqiu(通过 PG_DSN 连接)
|
||||
-- 说明:为 DWD/DWS 层共 35 张表创建带 site_id 行级过滤的 RLS 视图,
|
||||
-- 供业务库通过 postgres_fdw 只读访问。
|
||||
-- cfg_* 配置表无 site_id 列,视图直接 SELECT * 不加过滤。
|
||||
-- dim_member / dim_member_card_account 使用 register_site_id 列过滤。
|
||||
-- dim_staff_ex 无 site_id 列,视图直接 SELECT * 不加过滤。
|
||||
-- 需求:2.1, 2.2, 2.3, 2.4, 2.7, 2.8, 4.1, 4.3, 4.4, 4.5, 4.6
|
||||
-- =============================================================================
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 1. 创建 app Schema
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE SCHEMA IF NOT EXISTS app;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 2. 创建 app_reader 只读角色(条件创建)
|
||||
-- ---------------------------------------------------------------------------
|
||||
DO $$ BEGIN
|
||||
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'app_reader') THEN
|
||||
CREATE ROLE app_reader LOGIN;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 3. DWD 层 RLS 视图(11 张,全部含 site_id 过滤)
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- dim_member 使用 register_site_id 而非 site_id
|
||||
CREATE OR REPLACE VIEW app.v_dim_member AS
|
||||
SELECT * FROM dwd.dim_member
|
||||
WHERE register_site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dim_assistant AS
|
||||
SELECT * FROM dwd.dim_assistant
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
-- dim_member_card_account 使用 register_site_id 而非 site_id
|
||||
CREATE OR REPLACE VIEW app.v_dim_member_card_account AS
|
||||
SELECT * FROM dwd.dim_member_card_account
|
||||
WHERE register_site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dim_table AS
|
||||
SELECT * FROM dwd.dim_table
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dwd_settlement_head AS
|
||||
SELECT * FROM dwd.dwd_settlement_head
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dwd_table_fee_log AS
|
||||
SELECT * FROM dwd.dwd_table_fee_log
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dwd_assistant_service_log AS
|
||||
SELECT * FROM dwd.dwd_assistant_service_log
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dwd_recharge_order AS
|
||||
SELECT * FROM dwd.dwd_recharge_order
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dwd_store_goods_sale AS
|
||||
SELECT * FROM dwd.dwd_store_goods_sale
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dim_staff AS
|
||||
SELECT * FROM dwd.dim_staff
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
-- dim_staff_ex 无 site_id 列,直接 SELECT * 不加过滤
|
||||
CREATE OR REPLACE VIEW app.v_dim_staff_ex AS
|
||||
SELECT * FROM dwd.dim_staff_ex;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 4. DWS 层 RLS 视图 — 含 site_id 过滤(20 张)
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE OR REPLACE VIEW app.v_dws_member_consumption_summary AS
|
||||
SELECT * FROM dws.dws_member_consumption_summary
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_member_visit_detail AS
|
||||
SELECT * FROM dws.dws_member_visit_detail
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_member_winback_index AS
|
||||
SELECT * FROM dws.dws_member_winback_index
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_member_newconv_index AS
|
||||
SELECT * FROM dws.dws_member_newconv_index
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_member_recall_index AS
|
||||
SELECT * FROM dws.dws_member_recall_index
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_member_assistant_relation_index AS
|
||||
SELECT * FROM dws.dws_member_assistant_relation_index
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_member_assistant_intimacy AS
|
||||
SELECT * FROM dws.dws_member_assistant_intimacy
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_assistant_daily_detail AS
|
||||
SELECT * FROM dws.dws_assistant_daily_detail
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_assistant_monthly_summary AS
|
||||
SELECT * FROM dws.dws_assistant_monthly_summary
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_assistant_salary_calc AS
|
||||
SELECT * FROM dws.dws_assistant_salary_calc
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_assistant_customer_stats AS
|
||||
SELECT * FROM dws.dws_assistant_customer_stats
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_assistant_finance_analysis AS
|
||||
SELECT * FROM dws.dws_assistant_finance_analysis
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_finance_daily_summary AS
|
||||
SELECT * FROM dws.dws_finance_daily_summary
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_finance_income_structure AS
|
||||
SELECT * FROM dws.dws_finance_income_structure
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_finance_recharge_summary AS
|
||||
SELECT * FROM dws.dws_finance_recharge_summary
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_finance_discount_detail AS
|
||||
SELECT * FROM dws.dws_finance_discount_detail
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_finance_expense_summary AS
|
||||
SELECT * FROM dws.dws_finance_expense_summary
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_platform_settlement AS
|
||||
SELECT * FROM dws.dws_platform_settlement
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_assistant_recharge_commission AS
|
||||
SELECT * FROM dws.dws_assistant_recharge_commission
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_order_summary AS
|
||||
SELECT * FROM dws.dws_order_summary
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 5. DWS 层 cfg_* 配置表视图(4 张,无 site_id,直接 SELECT *)
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE OR REPLACE VIEW app.v_cfg_performance_tier AS
|
||||
SELECT * FROM dws.cfg_performance_tier;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_cfg_assistant_level_price AS
|
||||
SELECT * FROM dws.cfg_assistant_level_price;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_cfg_bonus_rules AS
|
||||
SELECT * FROM dws.cfg_bonus_rules;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_cfg_index_parameters AS
|
||||
SELECT * FROM dws.cfg_index_parameters;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 6. P2 预留(待 P2 完成后取消注释并创建视图)
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- TODO [P2] dws.dws_member_spending_power_index → app.v_dws_member_spending_power_index
|
||||
-- TODO [P2] dws.dws_assistant_order_contribution → app.v_dws_assistant_order_contribution
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 7. 授权:app_reader 对 app Schema 的只读访问
|
||||
-- ---------------------------------------------------------------------------
|
||||
GRANT USAGE ON SCHEMA app TO app_reader;
|
||||
GRANT SELECT ON ALL TABLES IN SCHEMA app TO app_reader;
|
||||
|
||||
-- 未来新建视图自动授权
|
||||
ALTER DEFAULT PRIVILEGES IN SCHEMA app GRANT SELECT ON TABLES TO app_reader;
|
||||
|
||||
-- =============================================================================
|
||||
-- 回滚脚本(按逆序执行)
|
||||
-- =============================================================================
|
||||
-- ALTER DEFAULT PRIVILEGES IN SCHEMA app REVOKE SELECT ON TABLES FROM app_reader;
|
||||
-- REVOKE SELECT ON ALL TABLES IN SCHEMA app FROM app_reader;
|
||||
-- REVOKE USAGE ON SCHEMA app FROM app_reader;
|
||||
-- DROP SCHEMA IF EXISTS app CASCADE;
|
||||
-- DROP ROLE IF EXISTS app_reader;
|
||||
Reference in New Issue
Block a user