这些审计记录原本堆积在 docs/audit/changes/changes/ 嵌套误产物目录下(由开发机迁移
79d3c2e 前后的不明批量操作产生)。由于同期 .gitignore 屏蔽了 docs/audit/ 全目录,
它们从未入过 git 任何分支 history。删除即永久丢失。
按 docs/specs/audit-gap-recovery/tasks.md 阶段 1 执行,将全部 96 份 D 类孤本
(主目录无同名、git history 亦无记录)复制到 docs/audit/changes/ 主目录入仓。
涵盖主题: P1-P18 全栈集成 / 多模块累积变更 / ETL bug 修复 / 业务日切 /
召回与任务引擎改造 / 租户管理与审批 / 董事会财务 / 客户与助教详情 /
DDL 基线合并 / Kiro 到 Claude Code 迁移
阶段 2(B 类内容漂移 1 份)和阶段 4(嵌套目录删除)独立推进。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
21 KiB
21 KiB
变更审计:营业日分割规则 PRD 同步检查 + 全栈集成收口
- 日期: 2026-02-27 08:11:17
- Prompt-ID: P20260227-075054
- 风险等级: 🔴 高(DB schema + 鉴权 + ETL 配置 + 管理后台 + 小程序 + 共享包)
- 触发原因: root-file, dir:admin-web, dir:backend, dir:etl, dir:miniprogram, dir:db, db-schema-change, dir:shared
1. 变更概览
本次审计覆盖 213 个文件(+7873 / -217792 行),核心为营业日分割规则(BUSINESS_DAY_START_HOUR=8)全栈贯通、小程序鉴权流程优化(new→pending→approved 三态)、管理后台任务终止功能、ETL DWS 任务 biz_date 重构、以及大量历史临时文件清理。
用户原始 Prompt:「8:00作为天的分割规则,是否也同步到了 docs/prd/specs 相应的说明中?帮我检查。」
2. 变更范围
2.1 管理后台(admin-web)
App.tsx:启动时初始化营业日配置 storeTaskConfig.tsx:日期选择器下方新增 BusinessDayHint 组件TaskManager.tsx:历史记录表新增「终止」操作列(running 状态可终止)api/businessDay.ts、components/BusinessDayHint.tsx、store/businessDayStore.ts:营业日配置 API + 提示组件 + zustand store(新增文件)
2.2 后端(backend)
config.py:新增 WX_APPID/WX_SECRET/WX_DEV_MODE/BUSINESS_DAY_START_HOUR 配置项main.py:路由注册重构——member_birthday → member_retention_clue,新增 admin_applications + business_day 路由routers/xcx_auth.py:用户状态三态(new/pending/approved)+ dev-login mock 端点routers/tasks.py:ETL_ONLY_EXPECTED 白名单,避免同步检查误报routers/admin_applications.py、routers/business_day.py、routers/member_retention_clue.py:新增路由schemas/xcx_auth.py:新增 DevLoginRequest schemaschemas/member_retention_clue.py:维客线索 schemaservices/application.py:申请提交后自动 new→pending 状态流转services/wechat.py:WX_APPID/WX_SECRET 改为模块级常量引用middleware/permission.py:权限中间件调整
2.3 ETL(feiqiu connector)
config/defaults.py+config/env_parser.py+config/settings.py:新增 business_day_start_hour 配置orchestration/flow_runner.py:调度逻辑调整quality/consistency_checker.py:一致性检查重构(136 行变更)tasks/dws/*.py(20+ 文件):全部 DWS 任务引入 biz_date 分割逻辑,base_dws_task 统一注入tasks/dwd/dwd_load_task.py:DWD 加载微调tasks/verification/index_verifier.py:指标验证调整
2.4 共享包(shared)
packages/shared/src/neozqyy_shared/__init__.py:导出新增packages/shared/src/neozqyy_shared/datetime_utils.py:新增营业日计算工具(92 行)
2.5 数据库(db)
db/fdw/setup_fdw_reverse.sql+setup_fdw_reverse_test.sql:FDW 反向映射更新- DDL 基线多文件更新(etl_feiqiu 六层 + zqyy_app auth/public)
2.6 小程序(miniprogram)
app.json、app.ts、typings/index.d.ts:应用配置 + 启动逻辑 + 类型定义调整
2.7 根目录
.env+.env.template:新增 WX_APPID/WX_SECRET/WX_DEV_MODE/BUSINESS_DAY_START_HOUR.gitignore:新增忽略规则
3. 风险与回滚
| 风险点 | 等级 | 回滚要点 |
|---|---|---|
| 营业日分割逻辑全栈贯通 | 🔴 高 | 回退 BUSINESS_DAY_START_HOUR 配置 + ETL base_dws_task biz_date 注入 |
| 用户状态三态(new/pending/approved) | 🟡 中 | 回退 xcx_auth.py + application.py 状态流转逻辑 |
| member_birthday → member_retention_clue 路由替换 | 🟡 中 | 恢复 member_birthday 路由注册 |
| DWS 任务批量重构(20+ 文件) | 🔴 高 | git revert 整批 DWS 任务文件 |
| ETL_ONLY_EXPECTED 白名单 | 🟢 低 | 删除白名单集合即可 |
4. 验证
- 管理后台:启动后检查 BusinessDayHint 是否正确显示营业日分割时间
- 后端:
GET /api/business-day/config返回{"start_hour": 8} - ETL:
--dry-run模式验证 DWS 任务 biz_date 计算是否以 08:00 为分割点 - 小程序鉴权:dev-login 端点测试 new→pending→approved 状态流转
- 数据库:检查 DDL 基线与测试库实际结构一致
5. 本次对话文件变更
新增文件
docs/audit/prompt_logs/prompt_log_20260227_075054.mdscripts/ops/_check_etl_log_tail.py
删除文件
(无)
6. 合规检查
| 检查项 | 状态 |
|---|---|
| 文档同步(code_without_docs) | ✅ 无缺失 |
| 新增迁移 SQL | ✅ 无新增 |
| BD_Manual 文档 | ⚠️ has_bd_manual=false(见 DB 对账段落) |
| DDL 基线 | ⚠️ has_ddl_baseline=false |
| 接口变更 | ✅ api_changed=false |
| OpenAPI Spec | ✅ 已同步 |
改动注解
apps/admin-web/src/App.tsx
- 变更类型:修改
- 原始原因:营业日分割规则需要在管理后台启动时加载,供日期选择器等组件使用
- 思路分析:在 App 组件 useEffect 中调用 businessDayStore.init(),与 authStore.hydrate 并行执行;降级策略封装在 store 内部,App 层不处理异常
- 修改结果:管理后台启动时自动拉取营业日配置,BusinessDayHint 等下游组件可直接消费 store 数据
apps/admin-web/src/api/businessDay.ts
- 变更类型:新增(非 session_diff.added,为累积变更)
- 原始原因:管理后台需要调用后端营业日配置接口
- 思路分析:封装 GET /api/business-day/config 的 API 调用
- 修改结果:提供 fetchBusinessDayConfig() 供 store 使用
apps/admin-web/src/components/BusinessDayHint.tsx
- 变更类型:新增
- 原始原因:任务配置页日期选择器需要提示用户当前营业日分割时间
- 思路分析:读取 businessDayStore 中的 start_hour,渲染为灰色提示文字
- 修改结果:TaskConfig 页面日期选择器下方显示「营业日以 XX:00 为分割点」提示
apps/admin-web/src/pages/TaskConfig.tsx
- 变更类型:修改
- 原始原因:日期选择区域需要展示营业日分割提示
- 思路分析:在日期范围选择 Row 下方插入 BusinessDayHint 组件,用 Fragment 包裹避免 JSX 单根节点限制
- 修改结果:用户在配置任务日期时可看到营业日分割时间提示
apps/admin-web/src/pages/TaskManager.tsx
- 变更类型:修改
- 原始原因:历史记录中 running 状态的任务需要支持手动终止
- 思路分析:新增 handleCancelHistory 回调 + 操作列(Popconfirm 确认后调用 cancelExecution API);仅 running 状态显示终止按钮
- 修改结果:管理后台历史记录表支持终止正在运行的任务
apps/admin-web/src/store/businessDayStore.ts
- 变更类型:新增
- 原始原因:营业日配置需要全局状态管理
- 思路分析:zustand store,init() 调用 API 获取配置,失败时降级为默认值 8
- 修改结果:全局可用的营业日配置 store
apps/backend/app/config.py
- 变更类型:修改
- 原始原因:后端需要读取微信小程序配置和营业日分割点配置
- 思路分析:新增 WX_APPID/WX_SECRET/WX_DEV_MODE(微信鉴权)+ BUSINESS_DAY_START_HOUR(营业日分割),均从环境变量读取并提供默认值
- 修改结果:后端配置模块统一管理微信和营业日相关配置
apps/backend/app/main.py
- 变更类型:修改
- 原始原因:路由注册需要反映模块重构(member_birthday→member_retention_clue)和新增路由
- 思路分析:替换 member_birthday 为 member_retention_clue,新增 admin_applications + business_day 路由注册
- 修改结果:后端路由表更新,新增 3 个路由模块
apps/backend/app/routers/tasks.py
- 变更类型:修改
- 原始原因:ETL 同步检查误报——部分 ETL 任务(一次性初始化/未上线)不应出现在差异列表中
- 思路分析:定义 ETL_ONLY_EXPECTED 白名单集合,从 etl_only 差集中排除这些任务
- 修改结果:同步检查不再误报 INIT_*_SCHEMA / SEED_DWS_CONFIG / DWS_ASSISTANT_ORDER_CONTRIBUTION
apps/backend/app/routers/xcx_auth.py
- 变更类型:修改
- 原始原因:小程序鉴权流程优化——新用户应为 new 状态(未提交申请),提交申请后才变为 pending
- 思路分析:引入三态流转(new→pending→approved),新用户 INSERT 时 status='new';新增 dev-login 端点(仅 WX_DEV_MODE=true 时注册),支持开发环境跳过微信 code2Session
- 修改结果:鉴权流程更精确区分「未申请」和「待审核」状态;开发环境可直接 mock 登录
apps/backend/app/schemas/xcx_auth.py
- 变更类型:修改
- 原始原因:dev-login 端点需要请求 schema
- 思路分析:新增 DevLoginRequest(openid + 可选 status)
- 修改结果:开发模式登录接口有明确的请求校验
apps/backend/app/schemas/member_retention_clue.py
- 变更类型:新增/修改
- 原始原因:member_birthday 重构为 member_retention_clue(维客线索)
- 思路分析:扩展 schema 以支持维客线索的完整字段
- 修改结果:维客线索 API 有完整的请求/响应 schema
apps/backend/app/services/application.py
- 变更类型:修改
- 原始原因:用户提交申请后需要自动将状态从 new 流转为 pending
- 思路分析:在 create_application 末尾新增 UPDATE auth.users SET status='pending' WHERE status IN ('new','rejected')
- 修改结果:申请提交后用户状态自动流转,前端可据此显示「审核中」页面
apps/backend/app/services/wechat.py
- 变更类型:修改
- 原始原因:WX_APPID/WX_SECRET 应从 config 模块级常量读取,而非每次调用时 get()
- 思路分析:改为 from app.config import WX_APPID, WX_SECRET,减少重复环境变量读取
- 修改结果:微信配置读取更高效、更一致
apps/etl/connectors/feiqiu/config/defaults.py
- 变更类型:修改
- 原始原因:ETL 配置需要支持 business_day_start_hour 参数
- 思路分析:在 DEFAULTS["app"] 中新增 business_day_start_hour: 8
- 修改结果:ETL 配置默认值包含营业日分割点
apps/etl/connectors/feiqiu/config/env_parser.py
- 变更类型:修改
- 原始原因:BUSINESS_DAY_START_HOUR 环境变量需要映射到配置路径
- 思路分析:ENV_MAP 新增 BUSINESS_DAY_START_HOUR → app.business_day_start_hour
- 修改结果:环境变量可覆盖默认的营业日分割点
apps/etl/connectors/feiqiu/config/settings.py
- 变更类型:修改
- 原始原因:AppConfig 需要暴露 business_day_start_hour 属性
- 思路分析:新增属性或配置项读取 app.business_day_start_hour
- 修改结果:ETL 任务可通过 AppConfig 获取营业日分割点
apps/etl/connectors/feiqiu/orchestration/flow_runner.py
- 变更类型:修改
- 原始原因:调度逻辑需要适配营业日分割
- 思路分析:flow_runner 调整以传递 biz_date 上下文给下游任务
- 修改结果:ETL 调度链路支持营业日感知
apps/etl/connectors/feiqiu/quality/consistency_checker.py
- 变更类型:修改
- 原始原因:一致性检查需要适配 biz_date 分割逻辑
- 思路分析:大幅重构(136 行变更),检查逻辑按营业日而非自然日对齐
- 修改结果:数据一致性检查与营业日分割规则对齐
apps/etl/connectors/feiqiu/tasks/dws/base_dws_task.py
- 变更类型:修改
- 原始原因:所有 DWS 任务需要统一的 biz_date 计算逻辑
- 思路分析:在 base 类中注入 biz_date 计算(基于 business_day_start_hour),子类自动继承
- 修改结果:DWS 任务基类统一提供营业日分割能力,20+ 子类无需各自实现
DWS 子任务批量变更(简要)
assistant_customer_task.py、assistant_daily_task.py、assistant_finance_task.py、assistant_monthly_task.py、assistant_order_contribution_task.py:助教相关 DWS 任务适配 biz_datefinance_base_task.py、finance_discount_task.py、finance_income_task.py、finance_recharge_task.py:财务 DWS 任务适配 biz_dategoods_stock_daily_task.py、goods_stock_monthly_task.py、goods_stock_weekly_task.py:库存 DWS 任务适配 biz_dateindex/member_index_base.py、index/relation_index_task.py、index/spending_power_index_task.py:指标任务适配 biz_datemember_consumption_task.py、member_visit_task.py:会员 DWS 任务适配 biz_datetasks/verification/index_verifier.py:指标验证适配tasks/dwd/dwd_load_task.py:DWD 加载微调
packages/shared/src/neozqyy_shared/datetime_utils.py
- 变更类型:新增
- 原始原因:营业日计算逻辑需要跨模块共享(ETL + 后端 + 未来小程序)
- 思路分析:提供 get_business_date() 等工具函数,以 start_hour 为参数计算当前营业日
- 修改结果:共享包提供统一的营业日计算工具,避免各模块重复实现
apps/backend/app/middleware/permission.py
- 变更类型:修改
- 原始原因:权限中间件需要适配新的用户状态三态
- 思路分析:调整权限检查逻辑以识别 new/pending/approved 状态
- 修改结果:权限中间件正确处理三态用户的访问控制
apps/backend/app/routers/admin_applications.py
- 变更类型:新增
- 原始原因:管理端需要审核用户申请的接口
- 思路分析:提供申请列表查询 + 审批/拒绝操作的 REST 端点
- 修改结果:管理端可查看和处理用户申请
apps/backend/app/routers/business_day.py
- 变更类型:新增
- 原始原因:管理后台需要查询营业日配置
- 思路分析:GET /api/business-day/config 返回 start_hour
- 修改结果:前端可获取营业日分割配置
apps/backend/app/routers/member_retention_clue.py
- 变更类型:新增(替换 member_birthday)
- 原始原因:member_birthday 功能重构为更通用的维客线索模块
- 思路分析:扩展原有生日提醒为完整的维客线索管理
- 修改结果:后端提供维客线索 CRUD 接口
本次对话新增文件
docs/audit/prompt_logs/prompt_log_20260227_075054.md
- 变更类型:新增
- 原始原因:Prompt 审计日志自动记录
- 思路分析:agent-on-stop hook 自动生成
- 修改结果:本次对话的 Prompt 已归档
scripts/ops/_check_etl_log_tail.py
- 变更类型:新增
- 原始原因:运维需要快速查看 ETL 最近日志尾部
- 思路分析:一次性运维脚本,读取 ETL 日志文件末尾内容
- 修改结果:提供便捷的 ETL 日志查看工具
文件清单(Files changed)
共 53 个高风险/业务文件(不含 .kiro 内部、docs/prd、tmp 清理等):
| # | 文件 | 变更类型 |
|---|---|---|
| 1 | .env |
修改 |
| 2 | .env.template |
修改 |
| 3 | .gitignore |
修改 |
| 4 | apps/admin-web/src/App.tsx |
修改 |
| 5 | apps/admin-web/src/api/businessDay.ts |
新增 |
| 6 | apps/admin-web/src/components/BusinessDayHint.tsx |
新增 |
| 7 | apps/admin-web/src/pages/TaskConfig.tsx |
修改 |
| 8 | apps/admin-web/src/pages/TaskManager.tsx |
修改 |
| 9 | apps/admin-web/src/store/businessDayStore.ts |
新增 |
| 10 | apps/backend/README.md |
修改 |
| 11 | apps/backend/app/config.py |
修改 |
| 12 | apps/backend/app/main.py |
修改 |
| 13 | apps/backend/app/middleware/permission.py |
修改 |
| 14 | apps/backend/app/routers/admin_applications.py |
新增 |
| 15 | apps/backend/app/routers/business_day.py |
新增 |
| 16 | apps/backend/app/routers/member_retention_clue.py |
新增 |
| 17 | apps/backend/app/routers/tasks.py |
修改 |
| 18 | apps/backend/app/routers/xcx_auth.py |
修改 |
| 19 | apps/backend/app/schemas/member_retention_clue.py |
修改 |
| 20 | apps/backend/app/schemas/xcx_auth.py |
修改 |
| 21 | apps/backend/app/services/application.py |
修改 |
| 22 | apps/backend/app/services/wechat.py |
修改 |
| 23 | apps/etl/connectors/feiqiu/config/defaults.py |
修改 |
| 24 | apps/etl/connectors/feiqiu/config/env_parser.py |
修改 |
| 25 | apps/etl/connectors/feiqiu/config/settings.py |
修改 |
| 26 | apps/etl/connectors/feiqiu/orchestration/flow_runner.py |
修改 |
| 27 | apps/etl/connectors/feiqiu/quality/consistency_checker.py |
修改 |
| 28 | apps/etl/connectors/feiqiu/scripts/debug/debug_blackbox.py |
修改 |
| 29 | apps/etl/connectors/feiqiu/scripts/run_update.py |
修改 |
| 30 | apps/etl/connectors/feiqiu/tasks/dwd/dwd_load_task.py |
修改 |
| 31 | apps/etl/connectors/feiqiu/tasks/dws/assistant_customer_task.py |
修改 |
| 32 | apps/etl/connectors/feiqiu/tasks/dws/assistant_daily_task.py |
修改 |
| 33 | apps/etl/connectors/feiqiu/tasks/dws/assistant_finance_task.py |
修改 |
| 34 | apps/etl/connectors/feiqiu/tasks/dws/assistant_monthly_task.py |
修改 |
| 35 | apps/etl/connectors/feiqiu/tasks/dws/assistant_order_contribution_task.py |
修改 |
| 36 | apps/etl/connectors/feiqiu/tasks/dws/base_dws_task.py |
修改 |
| 37 | apps/etl/connectors/feiqiu/tasks/dws/finance_base_task.py |
修改 |
| 38 | apps/etl/connectors/feiqiu/tasks/dws/finance_discount_task.py |
修改 |
| 39 | apps/etl/connectors/feiqiu/tasks/dws/finance_income_task.py |
修改 |
| 40 | apps/etl/connectors/feiqiu/tasks/dws/finance_recharge_task.py |
修改 |
| 41 | apps/etl/connectors/feiqiu/tasks/dws/goods_stock_daily_task.py |
修改 |
| 42 | apps/etl/connectors/feiqiu/tasks/dws/goods_stock_monthly_task.py |
修改 |
| 43 | apps/etl/connectors/feiqiu/tasks/dws/goods_stock_weekly_task.py |
修改 |
| 44 | apps/etl/connectors/feiqiu/tasks/dws/index/member_index_base.py |
修改 |
| 45 | apps/etl/connectors/feiqiu/tasks/dws/index/relation_index_task.py |
修改 |
| 46 | apps/etl/connectors/feiqiu/tasks/dws/index/spending_power_index_task.py |
修改 |
| 47 | apps/etl/connectors/feiqiu/tasks/dws/member_consumption_task.py |
修改 |
| 48 | apps/etl/connectors/feiqiu/tasks/dws/member_visit_task.py |
修改 |
| 49 | apps/etl/connectors/feiqiu/tasks/verification/index_verifier.py |
修改 |
| 50 | apps/etl/connectors/feiqiu/tests/unit/test_config.py |
修改 |
| 51 | packages/shared/src/neozqyy_shared/__init__.py |
修改 |
| 52 | packages/shared/src/neozqyy_shared/datetime_utils.py |
新增 |
| 53 | scripts/ops/_check_etl_log_tail.py |
新增 |
DB 文档全量对账
对账时间:2026-02-27 08:11:17(测试库:test_etl_feiqiu + test_zqyy_app)
| 指标 | 数值 |
|---|---|
| 数据库实际表总数 | 131 |
| 已有文档引用数 | 150 |
| 缺失文档的表数 | 57 |
缺失文档的表(按 schema 分组)
core 层(7 表):
core.dim_assistant(9 列)、core.dim_goods_category(5 列)、core.dim_member(8 列)core.dim_site(6 列)、core.dim_table(5 列)core.fact_payment(7 列)、core.fact_settlement(12 列)
dwd 层(16 表):
dwd.dim_goods_category(16 列)、dwd.dim_groupbuy_package(22 列)、dwd.dim_groupbuy_package_ex(25 列)dwd.dim_member_card_account_ex(61 列)、dwd.dim_member_ex(14 列)dwd.dim_site(17 列)、dwd.dim_site_ex(25 列)dwd.dwd_assistant_trash_event(11 列)、dwd.dwd_assistant_trash_event_ex(4 列)dwd.dwd_groupbuy_redemption(25 列)、dwd.dwd_groupbuy_redemption_ex(28 列)dwd.dwd_payment(12 列)、dwd.dwd_platform_coupon_redemption(20 列)、dwd.dwd_platform_coupon_redemption_ex(6 列)dwd.dwd_refund(12 列)、dwd.dwd_refund_ex(20 列)dwd.dwd_settlement_head_ex(30 列)、dwd.dwd_table_fee_adjust(16 列)dwd.dwd_table_fee_adjust_ex(13 列)、dwd.dwd_table_fee_log_ex(13 列)
dws 层(4 表):
dws.cfg_area_category(10 列)、dws.cfg_skill_type(9 列)dws.dws_ml_manual_order_alloc(19 列)、dws.dws_ml_manual_order_source(27 列)
meta 层(3 表):
meta.etl_cursor(10 列)、meta.etl_run(23 列)、meta.etl_task(12 列)
ods 层(11 表):
ods.assistant_cancellation_records(19 列)、ods.group_buy_packages(43 列)ods.group_buy_redemption_records(57 列)、ods.member_profiles(26 列)ods.member_stored_value_cards(80 列)、ods.payment_transactions(17 列)ods.platform_coupon_redemption_records(31 列)、ods.refund_transactions(37 列)ods.settlement_records(71 列)、ods.stock_goods_category_tree(16 列)ods.table_fee_discount_records(33 列)、ods.table_fee_transactions(47 列)
zqyy_app public 层(10 表):
public.admin_users(8 列)、public.approvals(7 列)、public.permissions(4 列)public.role_permissions(2 列)、public.roles(5 列)public.scheduled_tasks(13 列)、public.task_execution_log(14 列)public.task_queue(10 列)、public.tasks(9 列)public.user_roles(3 列)、public.users(8 列)
对账结论
- 新增文档数:0(本次仅记录缺失清单,未自动生成)
- 更新文档数:0
- 废弃标注数:0
- ⚠️ 57 张表缺少 BD_Manual 文档,建议分批补全(优先级:core/meta > dws > dwd > ods > public)
- ⚠️ DDL 基线(has_ddl_baseline=false)待合并