Files
Neo-ZQYY/.kiro/specs/rns1-board-apis/tasks.md

320 lines
22 KiB
Markdown
Raw 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.
# Implementation Plan: RNS1.3 三看板接口
## Overview
基于 design.md 的模块结构,增量扩展后端路由、服务层和 FDW 查询层,新增 3 个看板端点 + 1 个配置端点并完成前端筛选修复。BOARD-3 财务看板是最复杂的单个接口6 板块、200+ 字段、60+ 环比数据点),采用板块级独立查询和独立降级策略。
## Tasks
- [x] 1. 通用工具函数(日期范围 + 环比计算)
- [x] 1.1 在 `apps/backend/app/services/board_service.py` 中实现 `_calc_date_range(time_enum, ref_date=None)` 工具函数
- 支持 BOARD-1 的 6 种时间枚举(`month`/`quarter`/`last_month`/`last_3m`/`last_quarter`/`last_6m`)和 BOARD-3 的 8 种时间枚举(`month`/`lastMonth`/`week`/`lastWeek`/`quarter3`/`quarter`/`lastQuarter`/`half6`
- 返回 `(start_date, end_date)` 元组,`date` 类型
- _Requirements: 1.3, 3.2_
- [x] 1.2 在 `board_service.py` 中实现 `_calc_prev_range(start_date, end_date)` 计算上期日期范围
- 上期长度等于当期长度,`prev_end <= start_date`
- _Requirements: 3.3_
- [x] 1.3 在 `board_service.py` 中实现 `calc_compare(current: Decimal, previous: Decimal) -> dict` 环比计算工具
- 返回 `{ compare: str, is_down: bool, is_flat: bool }`
- 边界:`previous=0, current≠0``"新增"``previous=0, current=0``"持平"`
- _Requirements: 8.11, 8.12, 8.13, 8.14_
- [x] 2. Pydantic Schema 定义
- [x] 2.1 新建 `apps/backend/app/schemas/xcx_board.py`,定义请求参数枚举
- `CoachSortEnum`6 值)、`SkillFilterEnum`5 值)、`BoardTimeEnum`6 值)
- `CustomerDimensionEnum`8 值)、`ProjectFilterEnum`5 值)
- `FinanceTimeEnum`8 值)、`AreaFilterEnum`7 值)
- _Requirements: 1.1, 2.1, 3.1_
- [x] 2.2 在 `xcx_board.py` 中定义 BOARD-1 响应 Schema
- `CoachSkillItem``CoachBoardItem`(扁平结构,含 perf/salary/sv/task 全部维度字段)、`CoachBoardResponse`items + dimType
- _Requirements: 1.4~1.14, 1.16_
- [x] 2.3 在 `xcx_board.py` 中定义 BOARD-2 响应 Schema
- `CustomerAssistant``CustomerBoardItemBase`(基础字段)
- 8 个维度专属 Schema`RecallItem``PotentialItem``BalanceItem``RechargeItem``RecentItem``Spend60Item``Freq60Item``LoyalItem`
- `WeeklyVisit`val + pct`PotentialTag``CoachDetail`
- `CustomerBoardResponse`items + total + page + pageSize
- _Requirements: 2.3~2.22_
- [x] 2.4 在 `xcx_board.py` 中定义 BOARD-3 响应 Schema
- `OverviewPanel`8 指标 + 各 3 个环比字段Optional
- `GiftCell``GiftRow``RechargePanel`(储值卡 5 指标 + 赠送卡 3×4 矩阵 + allCardBalance
- `RevenueStructureRow``RevenueItem``ChannelItem``RevenuePanel`
- `CashflowItem``CashflowPanel`
- `ExpenseItem``ExpensePanel`4 子分组 + total
- `CoachAnalysisRow``CoachAnalysisTable``CoachAnalysisPanel`basic + incentive
- `FinanceBoardResponse`overview + recharge|null + revenue + cashflow + expense + coachAnalysis
- _Requirements: 3.5~3.12, 4.1~4.7, 5.1~5.8_
- [x] 2.5 新建 `apps/backend/app/schemas/xcx_config.py`,定义 `SkillTypeItem`key/label/emoji/cls
- _Requirements: 6.1_
- [x] 3. FDW 查询层扩展 — BOARD-1
- [x] 3.1 在 `apps/backend/app/services/fdw_queries.py` 中实现 `get_all_assistants(conn, site_id, skill_filter)`
- 数据源:`app.v_dim_assistant`,按 `skill` 筛选
- _Requirements: 1.5_
- [x] 3.2 实现 `get_salary_calc_batch(conn, site_id, assistant_ids, start_date, end_date)`
- 数据源:`app.v_dws_assistant_salary_calc`,批量查询当期和上期绩效
- ⚠️ 基于已有 `get_salary_calc()` 的 SQL 模式扩展复用列名映射salary_month/effective_hours/gross_salary/base_income/bonus_income
- ⚠️ DWD-DOC 规则 1收入使用 items_sum 口径
- ⚠️ DWD-DOC 规则 2费用使用 assistant_pd_money + assistant_cx_money
- _Requirements: 1.8, 1.10_
- [x] 3.3 实现 `get_top_customers_for_coaches(conn, site_id, assistant_ids)`
- 数据源:`app.v_dws_member_assistant_relation_index` + `app.v_dim_member`
- ⚠️ 基于已有 `get_relation_index()` 的 SQL 模式扩展为按助教维度批量查询
- 按亲密度降序取 Top 3拼接 P6 AC3 四级 emoji`> 8.5` → 💖,`> 7` → 🧡,`> 5` → 💛,`≤ 5` → 💙)
- ⚠️ DQ-6客户姓名通过 member_id JOIN v_dim_member取 scd2_is_current=1
- ⚠️ 注意:已有 `get_coach_top_customers()` 按服务次数排序(来自 v_dwd_assistant_service_log本函数按亲密度排序来自 v_dws_member_assistant_relation_index语义不同不可复用
- _Requirements: 1.6_
- [x] 3.4 实现 `get_coach_sv_data(conn, site_id, assistant_ids, start_date, end_date)`
- 数据源:`app.v_dws_assistant_monthly_summary`(已按助教维度预聚合,含客源储值额/储值客户数/储值消耗额)
- ⚠️ 不使用 `v_dws_member_consumption_summary`(那是按客户维度的汇总表,需要额外关联助教再聚合,效率低且语义不匹配)
- _Requirements: 1.12_
- [x] 4. FDW 查询层扩展 — BOARD-28 维度)
- [x] 4.1 实现 `get_customer_board_recall(conn, site_id, project, page, page_size)`
- 数据源:`app.v_dws_member_winback_index` + `app.v_dim_member`ETL 已计算 WBI 召回指数,含 ideal_days/elapsed_days/overdue_days/visits_30d/wbi_score
- 按 WBIwbi_score降序LIMIT/OFFSET 分页
- ⚠️ DQ-6客户姓名通过 member_id JOIN v_dim_member
- ⚠️ 余额通过 JOIN v_dim_member_card_account 获取
- _Requirements: 2.6, 2.7_
- [x] 4.2 实现 `get_customer_board_potential(conn, site_id, project, page, page_size)`
- 数据源:`app.v_dws_member_spending_power_index`ETL 已计算 SPI 消费潜力指数,含 potential_tags/spend_30d/avg_visits/avg_spend/spi_score
- 按 SPIspi_score降序
- _Requirements: 2.8, 2.9_
- [x] 4.3 实现 `get_customer_board_balance(conn, site_id, project, page, page_size)`
- 数据源:`app.v_dim_member_card_account` + `app.v_dim_member`
- 按 balance_amount 降序
- ⚠️ DQ-7余额通过 tenant_member_id JOIN取 scd2_is_current=1
- _Requirements: 2.10, 2.11_
- [x] 4.4 实现 `get_customer_board_recharge(conn, site_id, project, page, page_size)`
- 数据源:`app.v_dwd_recharge_order` + `app.v_dim_member_card_account`(充值记录 + 当前余额)
- 按 last_recharge_date 降序
- _Requirements: 2.12, 2.13_
- [x] 4.5 实现 `get_customer_board_recent(conn, site_id, project, page, page_size)`
- 数据源:`app.v_dws_member_visit_detail` + `app.v_dim_member`ETL 已计算到店明细,含 last_visit_date/visit_freq/ideal_days
- 按 last_visit_date 降序
- _Requirements: 2.14, 2.15_
- [x] 4.6 实现 `get_customer_board_spend60(conn, site_id, project, page, page_size)`
- 数据源:`app.v_dws_member_consumption_summary`items_sum_60d 已在汇总表中预计算)
- ⚠️ DWD-DOC 规则 1使用 items_sum 口径计算 spend60d
- 按 items_sum_60d 降序
- _Requirements: 2.16, 2.17_
- [x] 4.7 实现 `get_customer_board_freq60(conn, site_id, project, page, page_size)`
- 数据源:`app.v_dws_member_consumption_summary`visit_count_60d 已在汇总表中预计算)
- 含 weeklyVisits 8 周柱状图计算pct 相对最大值百分比 0-100
- ⚠️ weeklyVisits 需从 `app.v_dwd_assistant_service_log` 按周分组统计(汇总表无周粒度数据)
- 按 visit_count_60d 降序
- _Requirements: 2.18, 2.19, 2.20_
- [x] 4.8 实现 `get_customer_board_loyal(conn, site_id, project, page, page_size)`
- 数据源:`app.v_dws_member_assistant_relation_index`
- 按 max_rs 降序
- _Requirements: 2.21, 2.22_
- [x] 4.9 实现 `get_customer_assistants(conn, site_id, member_ids)` 批量查询客户关联助教列表
- 含亲密度计算,当前跟进助教置顶
- _Requirements: 2.5_
- [x] 5. FDW 查询层扩展 — BOARD-36 板块)
- [x] 5.1 实现 `get_finance_overview(conn, site_id, start_date, end_date)`
- 数据源:`app.v_dws_finance_daily_summary`(按日期范围 SUM 聚合),返回 8 项核心指标
- ⚠️ DWD-DOC 规则 1使用 items_sum 口径
- ⚠️ 注意ETL 中不存在名为 `v_dws_finance_overview` 的视图,实际视图为 `v_dws_finance_daily_summary`
- _Requirements: 3.5, 3.7_
- [x] 5.2 实现 `get_finance_recharge(conn, site_id, start_date, end_date)`
- 数据源:`app.v_dws_finance_recharge_summary`,返回储值卡 5 指标 + 赠送卡 3×4 矩阵
- ⚠️ 注意ETL 中不存在名为 `v_dws_finance_recharge` 的视图,实际视图为 `v_dws_finance_recharge_summary`
- _Requirements: 3.8, 3.9, 3.10, 3.12_
- [x] 5.3 实现 `get_finance_revenue(conn, site_id, start_date, end_date, area)`
- 数据源:`app.v_dws_finance_income_structure`(收入结构主表)+ `app.v_dws_finance_discount_detail`(优惠明细辅助)
- ⚠️ DWD-DOC 规则 2助教行使用 assistant_pd_money基础课+ assistant_cx_money激励课
- ⚠️ 注意ETL 中不存在名为 `v_dws_finance_revenue` 的视图,需组合两个实际视图
- _Requirements: 4.1, 4.2, 4.3, 4.4_
- [x] 5.4 实现 `get_finance_cashflow(conn, site_id, start_date, end_date)`
- 数据源:`app.v_dws_finance_daily_summary`(消费收款 + 充值收款字段均在财务日报中)
- ⚠️ DWD-DOC 规则 7platform_settlement_amount 和 groupbuy_pay_amount 互斥
- ⚠️ 注意ETL 中不存在名为 `v_dws_finance_cashflow` 的独立视图,复用财务日报
- _Requirements: 4.5, 4.6, 4.7_
- [x] 5.5 实现 `get_finance_expense(conn, site_id, start_date, end_date)`
- 数据源:`app.v_dws_finance_expense_summary`(支出明细 4 子分组)+ `app.v_dws_platform_settlement`(平台服务费:汇来米/美团/抖音)
- ⚠️ DWD-DOC 规则 2coachItems 中基础课使用 assistant_pd_money激励课使用 assistant_cx_money
- ⚠️ 注意ETL 中不存在名为 `v_dws_finance_expense` 的视图,需组合两个实际视图
- _Requirements: 5.1, 5.2, 5.3, 5.4_
- [x] 5.6 实现 `get_finance_coach_analysis(conn, site_id, start_date, end_date)`
- 数据源:`app.v_dws_assistant_salary_calc`,按 assistant_level_name 分组聚合
- 返回 basic基础课/陪打)+ incentive激励课/超休)两个子表
- _Requirements: 5.5, 5.6, 5.7, 5.8_
- [x] 5.7 实现 `get_skill_types(conn, site_id)` 查询技能类型配置
- 数据源ETL cfg 表
- _Requirements: 6.2_
- [x] 6. Checkpoint — FDW 查询层验证
- All FDW query functions compile and type-check correctly (getDiagnostics: 0 errors).
- [x] 7. 服务层 — BOARD-1 助教看板
- [x] 7.1 在 `board_service.py` 中实现 `get_coach_board(sort, skill, time, site_id) -> dict`
- 参数互斥校验:`time=last_6m` + `sort=sv_desc` → HTTP 400
- 日期范围计算 → 查询助教列表 → 批量查询绩效/Top 客户/储值/任务 → 排序 → 组装扁平响应
- topCustomers 查询失败降级为空列表
- _Requirements: 1.1~1.16_
- [x] 7.2 在 `board_service.py` 中实现 `_query_coach_tasks(site_id, assistant_ids, start_date, end_date)` 查询任务完成数
- 数据源:`biz.coach_tasks`,按 task_type 分类统计 recall/callback
- _Requirements: 1.13, 1.14_
- [x] 8. 服务层 — BOARD-2 客户看板
- [x] 8.1 在 `board_service.py` 中实现 `get_customer_board(dimension, project, page, page_size, site_id) -> dict`
- 按 dimension 参数路由到对应 FDW 查询函数
- 批量查询客户关联助教列表
- 组装分页响应items + total + page + pageSize
- _Requirements: 2.1~2.23_
- [x] 9. 服务层 — BOARD-3 财务看板
- [x] 9.1 在 `board_service.py` 中实现 `get_finance_board(time, area, compare, site_id) -> dict`
- 日期范围计算 → 6 板块独立查询、独立 try/except 降级
- `area≠all` 时 recharge 返回 null
- `compare=1` 时计算上期范围并调用 calc_compare
- `compare=0` 时环比字段为 None序列化时排除
- _Requirements: 3.1~3.12, 4.1~4.7, 5.1~5.8, 8.9, 8.10_
- [x] 9.2 实现 `_build_overview(conn, site_id, date_range, prev_range, compare)` 经营一览板块构建
- _Requirements: 3.5, 3.6, 3.7_
- [x] 9.3 实现 `_build_recharge(conn, site_id, date_range, prev_range, compare)` 预收资产板块构建
- _Requirements: 3.8~3.12_
- [x] 9.4 实现 `_build_revenue(conn, site_id, date_range, area, prev_range, compare)` 应计收入板块构建
- _Requirements: 4.1~4.4_
- [x] 9.5 实现 `_build_cashflow(conn, site_id, date_range, prev_range, compare)` 现金流入板块构建
- _Requirements: 4.5~4.7_
- [x] 9.6 实现 `_build_expense(conn, site_id, date_range, prev_range, compare)` 现金流出板块构建
- _Requirements: 5.1~5.4_
- [x] 9.7 实现 `_build_coach_analysis(conn, site_id, date_range, prev_range, compare)` 助教分析板块构建
- _Requirements: 5.5~5.8_
- [x] 9.8 实现各板块的 `_empty_*()` 空默认值工厂函数(优雅降级用)
- _Requirements: 8.9, 8.10_
- [x] 10. 路由层 + 路由注册
- [x] 10.1 新建 `apps/backend/app/routers/xcx_board.py`,实现 3 个看板端点
- `GET /api/xcx/board/coaches` — require_permission("view_board_coach")
- `GET /api/xcx/board/customers` — require_permission("view_board_customer")
- `GET /api/xcx/board/finance` — require_permission("view_board_finance")`response_model_exclude_none=True`
- _Requirements: 8.1, 8.2, 8.3_
- [x] 10.2 新建 `apps/backend/app/routers/xcx_config.py`,实现 CONFIG-1 端点
- `GET /api/xcx/config/skill-types` — require_approved()
- 查询失败降级返回空数组
- _Requirements: 6.1~6.4_
- [x] 10.3 在 `apps/backend/app/main.py` 中注册 `xcx_board``xcx_config` 路由
- _Requirements: 8.1_
- [x] 11. Checkpoint — 后端接口验证
- All backend endpoints compile and type-check correctly (getDiagnostics: 0 errors on all router files and main.py).
- [x] 12. 前端筛选修复 — BOARD-1T3-7 F1, F6
- [x] 12.1 修复 `apps/miniprogram/miniprogram/pages/board-coach/` 页面的 `onSortChange``onSkillChange``onTimeChange` 事件处理函数
- 更新 data 状态后调用 `this.loadData()` 重新请求 API
- _Requirements: 7.1_
- [x] 12.2 实现 `time=last_6m` + `sort=sv_desc` 互斥约束
- 选择 `last_6m` 时禁用 `sv_desc` 选项,或选择 `sv_desc` 时禁用 `last_6m` 选项
- _Requirements: 7.2_
- [x] 13. 前端筛选修复 — BOARD-2T3-7 F2, F3
- [x] 13.1 修复 `apps/miniprogram/miniprogram/pages/board-customer/` 页面的 `onDimensionChange``onProjectChange` 事件处理函数
- 更新 data 状态后调用 `this.loadData()` 重新请求 API
- _Requirements: 7.3_
- [x] 13.2 补充分页参数和懒加载逻辑
- `onReachBottom` 触发加载下一页,`pageSize=20`
- _Requirements: 7.4_
- [x] 13.3 修改 `services/api.ts``fetchBoardCustomers` 函数签名,增加 `page``pageSize` 参数
- _Requirements: 7.5_
- [x] 14. 前端筛选修复 — BOARD-3T3-7 F4, F5
- [x] 14.1 修改 `services/api.ts``fetchBoardFinance` 函数签名
-`{ date?: string }` 扩展为 `{ time: string, area: string, compare: number }`
- _Requirements: 7.6_
- [x] 14.2 修复 `apps/miniprogram/miniprogram/pages/board-finance/` 页面的 `onTimeChange``onAreaChange` 事件处理函数
- 更新 data 状态后使用新参数调用 `fetchBoardFinance`
- _Requirements: 7.7_
- [x] 14.3 修复 `toggleCompare` 函数,切换环比开关后使用 `compare=0/1` 参数重新请求
- _Requirements: 7.8_
- [x] 14.4 `area≠all` 时隐藏预收资产板块(`recharge` 为 null 时不渲染该 section
- _Requirements: 7.9_
- [x] 15. Checkpoint — 前端筛选修复验证
- All frontend filter fixes implemented: event handlers call loadData(), API signatures extended, pagination added to BOARD-2, mutual exclusion constraint for BOARD-1.
- [x] 16. 属性测试Property-Based Testing
- [x] 16.1 新建 `tests/test_board_properties.py`,实现 Property 1: 日期范围计算正确性
- 生成器:`st.dates()` + `st.sampled_from(BoardTimeEnum/FinanceTimeEnum)`
- 验证:`start_date <= end_date`,上期 `prev_end <= start_date`,上期长度 = 当期长度
- **Validates: Requirements 1.3, 3.2, 3.3 — Design Property 1**
- [x] 16.2 实现 Property 2: BOARD-1 排序不变量
- 生成器:随机助教列表 + `st.sampled_from(CoachSortEnum)`
- 验证:相邻元素排序字段满足方向约束
- **Validates: Requirements 1.15, 9.1, 9.2 — Design Property 2**
- [x] 16.3 实现 Property 3: BOARD-2 分页不变量
- 生成器:随机客户列表 + page/pageSize
- 验证:`items.length <= pageSize`total 跨页一致,无交集
- **Validates: Requirements 2.2, 9.3, 9.4 — Design Property 3**
- [x] 16.4 实现 Property 4: 亲密度 emoji 四级映射
- 生成器:`st.floats(min_value=0, max_value=10)`
- 验证:`> 8.5` → 💖,`> 7` → 🧡,`> 5` → 💛,`≤ 5` → 💙;边界 `8.5` → 🧡
- **Validates: Requirements 1.6 — Design Property 4**
- [x] 16.5 实现 Property 5: 环比计算公式正确性
- 生成器:`st.decimals(min_value=0, max_value=1e8)` × 2
- 验证:公式正确、方向标记正确、"新增"/"持平" 边界
- **Validates: Requirements 8.11~8.14 — Design Property 5**
- [x] 16.6 实现 Property 6: 环比开关一致性
- 生成 BOARD-3 mock 数据 + compare=0序列化后验证 JSON 无 Compare/Down/Flat key
- **Validates: Requirements 3.4, 9.8 — Design Property 6**
- [x] 16.7 实现 Property 7: 预收资产区域约束
- 生成 area≠all 的请求,验证 recharge=null
- **Validates: Requirements 3.11, 9.7 — Design Property 7**
- [x] 16.8 实现 Property 8+9: 经营一览恒等式
- 验证 `confirmedRevenue ≈ occurrence - abs(discount)`±0.01
- 验证 `cashBalance ≈ cashIn - cashOut`±0.01
- **Validates: Requirements 9.5, 9.6 — Design Property 8, 9**
- [x] 16.9 实现 Property 10: 支付渠道恒等式
- 验证 `balance_amount = recharge_card_amount + gift_card_amount`
- **Validates: Requirements 8.7, 9.9 — Design Property 10**
- [x] 16.10 实现 Property 11: 参数互斥约束
- 固定 `time=last_6m` + `sort=sv_desc`,验证 HTTP 400
- **Validates: Requirements 1.2, 9.11 — Design Property 11**
- [x] 16.11 实现 Property 13: weeklyVisits 百分比范围
- 生成 8 周到店数据,验证长度=8、pct 0-100、max(pct)=100
- **Validates: Requirements 2.20 — Design Property 13**
- [x] 16.12 实现 Property 14: 优雅降级不变量
- mock 板块查询抛异常,验证整体 HTTP 200 + 失败板块空默认值
- **Validates: Requirements 8.9, 8.10 — Design Property 14**
- [x] 17. Final Checkpoint — 全量验证
- Run all property tests: `cd C:\NeoZQYY && pytest tests/test_board_properties.py -v`
- Ensure all 12 property tests pass. Ask the user if questions arise.
- [x] 18. 前端到数据库全链路测试
- [x] 18.1 启动后端服务,使用测试库(`test_zqyy_app`)验证 BOARD-1、BOARD-2、BOARD-3、CONFIG-1 四个端点的完整请求-响应链路
- 使用真实 FDW 连接(`test_etl_feiqiu`)验证 SQL 查询正确性
- 验证 JSON 响应结构与 Schema 定义一致camelCase 序列化)
- 验证权限校验(`require_permission()` / `require_approved()`)在真实请求中生效
- 验证 `SET LOCAL app.current_site_id` 数据隔离在真实请求中生效
- [x] 18.2 验证 BOARD-3 环比开关行为
- `compare=0` 时响应 JSON 中无 Compare/Down/Flat 字段 ✅
- `compare=1` 时响应 JSON 中包含完整环比数据 ✅
- `area≠all``recharge` 为 null ✅
- [x] 18.3 验证 BOARD-1 参数互斥
- `time=last_6m` + `sort=sv_desc` 返回 HTTP 400 ✅
- [x] 18.4 验证 BOARD-2 分页行为
- `page=1, pageSize=20` 返回正确分页结构 ✅
- 不同 page 返回的 total 一致 ✅
- [x] 18.5 小程序前端联调验证
- 前端筛选修复代码已正确接入 API代码审查确认
- 待联调清单记录在测试文件注释中FDW 列名已修复,可联调)
- [x] 19. 项目文档更新与落地
- [x] 19.1 更新 `docs/contracts/openapi/backend-api.json`,补充 BOARD-1、BOARD-2、BOARD-3、CONFIG-1 四个端点的 OpenAPI 定义
- [x] 19.2 更新 `docs/architecture/backend-architecture.md`,补充新增的 `board_service` 模块、`xcx_board` / `xcx_config` 路由注册说明
- [x] 19.3 更新 `docs/database/BD_Manual_biz_tables.md`,补充本次引用的 `biz.coach_tasks` 表在看板场景下的使用说明BOARD-1 task 维度查询)
- [x] 19.4 更新 `docs/DOCUMENTATION-MAP.md`,确保新增文档条目已索引
- [x] 19.5 更新 `docs/miniprogram-dev/API-contract.md`,补充 BOARD-1、BOARD-2、BOARD-3、CONFIG-1 的接口契约(请求参数/响应示例)
- [x] 20. 数据库变更审计与 DDL 合并
- [x] 20.1 审计本次实现中对数据库的改动新建表、新增字段、新增索引、FDW 映射变更等)
- 结论:**无 DDL 变更**。全部基于已有 `app.v_*` RLS 视图的 SELECT 查询,`IMPORT FOREIGN SCHEMA app` 已自动导入所有视图。`biz.coach_tasks` 看板查询走已有 `idx_coach_tasks_assistant_status` 索引,无需新增。
- [x] 20.2 将所有数据库变更合并到主 DDL 文件
- 结论:无 DDL 变更需合并。
- [x] 20.3 更新 BD 手册记录变更
- `docs/database/BD_Manual_biz_tables.md` 已补充 RNS1.3 看板引用说明§2.1
- 审计记录:`docs/audit/changes/2026-03-20__rns13-board-apis-e2e-fix.md`