Files
Neo-ZQYY/scripts/ops/run_seed_spi_params.py
Neo b25308c3f4 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 排除规则
2026-02-26 08:03:53 +08:00

147 lines
4.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""
在测试库 test_etl_feiqiu 执行 SPI 种子数据脚本。
种子脚本db/etl_feiqiu/seeds/seed_index_parameters.sql
目标表dws.cfg_index_parametersindex_type='SPI'
使用方式:
python scripts/ops/run_seed_spi_params.py
"""
import os
import sys
from pathlib import Path
from dotenv import load_dotenv
import psycopg2
# 加载根 .env
_ROOT = Path(__file__).resolve().parents[2]
load_dotenv(_ROOT / ".env", override=False)
DSN = os.getenv("TEST_DB_DSN")
if not DSN:
print("ERROR: TEST_DB_DSN 未配置,请在根 .env 中设置")
sys.exit(1)
SEED_FILE = _ROOT / "db" / "etl_feiqiu" / "seeds" / "seed_index_parameters.sql"
def execute_seed(conn) -> bool:
"""执行种子数据脚本,返回是否成功"""
sql = SEED_FILE.read_text(encoding="utf-8")
if not sql.strip():
print("⚠️ 种子脚本为空,跳过")
return False
try:
cur = conn.cursor()
cur.execute(sql)
cur.close()
conn.commit()
print("✅ 种子数据脚本执行成功")
return True
except Exception as e:
conn.rollback()
print(f"❌ 种子数据脚本执行失败: {e}")
return False
def verify(conn) -> bool:
"""验证 SPI 参数插入结果"""
cur = conn.cursor()
checks = []
# 1. SPI 参数总数(应为 28 个)
cur.execute("""
SELECT COUNT(*) FROM dws.cfg_index_parameters
WHERE index_type = 'SPI'
""")
spi_count = cur.fetchone()[0]
checks.append((f"SPI 参数数量 = {spi_count}(期望 28", spi_count == 28))
# 2. 关键参数存在且值正确
key_params = [
("weight_level", 0.60),
("weight_speed", 0.30),
("weight_stability", 0.10),
("amount_base_spend_30", 500.0),
("compression_mode", 1.0),
]
for pname, expected in key_params:
cur.execute("""
SELECT param_value FROM dws.cfg_index_parameters
WHERE index_type = 'SPI' AND param_name = %s
ORDER BY effective_from DESC LIMIT 1
""", (pname,))
row = cur.fetchone()
if row:
actual = float(row[0])
ok = abs(actual - expected) < 1e-6
checks.append((f" {pname} = {actual}(期望 {expected}", ok))
else:
checks.append((f" {pname} 缺失", False))
# 3. 权重归一化Level 子分权重之和 = 1.0
cur.execute("""
SELECT SUM(param_value) FROM dws.cfg_index_parameters
WHERE index_type = 'SPI'
AND param_name IN ('w_level_spend_30', 'w_level_spend_90',
'w_level_ticket_90', 'w_level_recharge_90')
""")
level_sum = float(cur.fetchone()[0] or 0)
checks.append((f" Level 权重之和 = {level_sum:.2f}(期望 1.00", abs(level_sum - 1.0) < 1e-6))
# 4. 总分权重之和 = 1.0
cur.execute("""
SELECT SUM(param_value) FROM dws.cfg_index_parameters
WHERE index_type = 'SPI'
AND param_name IN ('weight_level', 'weight_speed', 'weight_stability')
""")
total_sum = float(cur.fetchone()[0] or 0)
checks.append((f" 总分权重之和 = {total_sum:.2f}(期望 1.00", abs(total_sum - 1.0) < 1e-6))
cur.close()
print("\n" + "=" * 50)
print("SPI 种子数据验证结果")
print("=" * 50)
all_ok = True
for name, ok in checks:
status = "" if ok else ""
print(f" {status} {name}")
if not ok:
all_ok = False
return all_ok
def main():
dsn_display = DSN.split("@")[1] if "@" in DSN else DSN
print(f"连接测试库: {dsn_display}")
print(f"种子脚本: {SEED_FILE.name}\n")
if not SEED_FILE.exists():
print(f"ERROR: 种子脚本不存在: {SEED_FILE}")
sys.exit(1)
conn = psycopg2.connect(DSN)
if not execute_seed(conn):
conn.close()
sys.exit(1)
all_ok = verify(conn)
conn.close()
if all_ok:
print("\n✅ SPI 种子数据执行完成,所有验证通过")
else:
print("\n⚠️ 部分验证未通过,请检查")
sys.exit(1)
if __name__ == "__main__":
main()