Files
Neo-ZQYY/docs/specs/admin-web-enhancement/tasks.md
Neo 70324d8542 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>
2026-04-06 00:02:37 +08:00

17 KiB
Raw Blame History

实施计划NS4.1 + P16 — Admin-Web 管理后台增强

权威参考:实施过程中如遇细节不明确,应优先查阅 PRD 原文:

  • docs/prd/Neo_Specs/NS4.1-tenant-admin-redesign.md — NS4.1 完整设计(数据模型 DDL、页面布局、接口设计、迁移步骤、边界条件
  • docs/prd/specs/P16-task-min-run-interval.md — P16 完整设计调度器逻辑、API 扩展、前端变更、边界条件)

概述

按依赖关系分两条并行线实施:模块 ANS4.1 注册体系 + 租户管理员重构)和模块 BP16 调度任务间隔。两者改动文件无重叠可交替执行。整体顺序DDL 迁移 → 后端 API → 前端页面 → 数据迁移/切换 → 收尾。

后端使用 PythonFastAPI + Pydantic前端使用 TypeScriptReact + Vite + Ant Design

任务

阶段一DDL 迁移(模块 A + B

  • 1. DDL 迁移 — 模块 A注册体系四张新表

    • 1.1 创建迁移脚本 db/zqyy_app/migrations/2026-03-22__ns41_registry_tables.sql
      • CREATE TABLE biz.connectorsid SERIAL PK, connector_key VARCHAR(50) UNIQUE, display_name, is_active, created_at
      • CREATE TABLE biz.tenantsid SERIAL PK, connector_id FK, tenant_id BIGINT, tenant_name, is_active, created_at, updated_at, UNIQUE(connector_id, tenant_id)
      • CREATE TABLE biz.sitesid SERIAL PK, tenant_id FK, site_id BIGINT UNIQUE, site_name, site_code VARCHAR(6) UNIQUE, site_label, is_active, created_at, updated_at
      • CREATE TABLE biz.site_code_historyid SERIAL PK, site_id BIGINT, site_code VARCHAR(6) UNIQUE, is_current BOOLEAN, created_at, retired_at
      • INSERT 种子数据connectors('feiqiu')、tenants(朗朗桌球)
      • INSERT 迁移数据:从 auth.site_code_mapping 迁移真实数据到 biz.sites,创建 site_code_history 记录
      • 编写回滚脚本(逆序 DROP TABLE
      • 需求: A1.1, A1.2, A1.3, A1.4, A1.5
  • 2. DDL 迁移 — 模块 Bscheduled_tasks 新增字段

    • 2.1 创建迁移脚本 db/zqyy_app/migrations/2026-03-22__p16_min_run_interval.sql
      • ALTER TABLE scheduled_tasks ADD COLUMN min_run_interval_value INTEGER NOT NULL DEFAULT 0
      • ALTER TABLE scheduled_tasks ADD COLUMN min_run_interval_unit VARCHAR(20) NOT NULL DEFAULT 'minutes'
      • ALTER TABLE scheduled_tasks ADD COLUMN last_success_at TIMESTAMPTZ
      • 添加 COMMENT ON COLUMN 注释
      • 编写回滚脚本ALTER TABLE DROP COLUMN
      • 需求: B1.1, B1.2

阶段二:后端 API — 模块 A注册体系 + 管理员重构)

  • 3. 后端 Schema — 注册体系

    • 3.1 创建 apps/backend/app/schemas/admin_registry.py

      • 定义 TenantItemid, tenant_id, tenant_name, connector_name, is_active
      • 定义 SiteItemid, site_id, site_name, site_code, site_label, is_active
      • 定义 UpdateSiteCodeRequestnew_code: str
      • 定义 SiteCodeResultsite_id, old_code, new_code, history_cleaned
      • 定义 SiteCodeHistoryItemid, site_code, is_current, created_at, retired_at
      • 需求: A2.1, A2.2, A2.4, A2.5
    • 3.2 修改 apps/backend/app/schemas/admin_tenant_admins.py

      • TenantAdminListItem 新增 tenant_name 字段
      • TenantAdminCreateRequest 添加字段说明注释tenant_id 从 biz.tenants 选择)
      • 需求: A2.6
  • 4. 后端路由 — 注册体系 API

    • 4.1 创建 apps/backend/app/routers/admin_registry.py

      • GET /api/admin/tenants — 所有活跃租户列表JOIN biz.connectors 获取 connector_name
      • GET /api/admin/tenants/{tenant_id}/sites — 指定租户下所有活跃店铺
      • PUT /api/admin/sites/{site_id}/site-code — 设置/修改简写ID事务内执行
        • 校验格式6 位3+3统一大写
        • 校验全局唯一biz.sites + biz.site_code_history
        • 事务:旧 code 标记 retired → 新 code 插入 history → 更新 sites.site_code
        • 检查旧 code 是否有未审核申请引用,决定是否清理历史记录
      • GET /api/admin/sites/{site_id}/site-code-history — 简写ID 变更历史
      • 需求: A2.1, A2.2, A2.4, A2.5, A3.1, A3.2, A3.3, A3.4
    • 4.2 在 apps/backend/app/main.py 中注册 admin_registry router

      • 需求: A2.1
  • 5. 后端路由 — 管理员 CRUD 扩展

    • 5.1 修改 apps/backend/app/routers/admin_tenant_admins.py
      • 新增 DELETE /api/admin/tenant-admins/{id} — 软删除is_active=false已禁用返回 409
      • 修改 POST /api/admin/tenant-admins — 创建时校验 tenant_id 在 biz.tenants 中存在
      • 修改 GET /api/admin/tenant-admins — 默认 is_active=true新增 include_inactive 查询参数
      • 修改 PATCH /api/admin/tenant-admins/{id} — 支持修改 username(校验全局唯一性,冲突返回 409
      • 列表查询 JOIN biz.tenants 获取 tenant_name
      • 需求: A2.3, A2.6, A2.7, A2.8, A4.1
  • 6. 编写属性测试 — 模块 A

    • 6.1 创建 tests/test_site_code_props.py

      • Property 1: 简写ID 全局唯一性 — 使用 Hypothesis 生成随机 code验证已存在的 code 被拒绝
      • Property 2: 简写ID 变更事务完整性 — 验证事务后 sites.site_code、history.is_current、history.retired_at 状态一致
      • Property 3: 简写ID 格式校验 — 生成随机字符串,验证仅 6 位 3+3 格式通过
      • 验证: 需求 A3.1, A3.2
    • 6.2 创建 tests/test_tenant_admin_props.py(扩展已有文件或新建)

      • Property 4: 租户管理员软删除一致性 — 删除后默认列表不返回include_inactive 返回
      • 验证: 需求 A2.3, A2.7
  • 7. 检查点 — 模块 A 后端验证

    • 确保注册体系 API 和管理员 CRUD 扩展所有测试通过ask the user if questions arise.

阶段三:后端 API — 模块 B调度器间隔

  • 8. 后端 Schema + 路由 — 调度器间隔

    • 8.1 修改 apps/backend/app/schemas/schedules.py

      • CreateScheduleRequest 新增 min_run_interval_valueint, default=0min_run_interval_unitstr, default='minutes'
      • UpdateScheduleRequest 新增同上两个可选字段
      • ScheduleResponse 新增 min_run_interval_valuemin_run_interval_unitlast_success_at
      • 需求: B3.1, B3.2
    • 8.2 修改 apps/backend/app/services/scheduler.py

      • 新增 _convert_interval_to_seconds(value, unit) 辅助函数
      • 扩展 check_and_enqueue() SQL 查询:新增读取 min_run_interval_value, min_run_interval_unit, last_run_at, last_status
      • 新增并发检查last_status == 'running' → 跳过,日志记录 skipped_concurrent
      • 新增间隔检查min_run_interval_value > 0 且 now - last_run_at < min_interval → 跳过,推进 next_run_at
      • 需求: B2.1, B2.2, B2.4
    • 8.3 修改任务完成回调(scheduler.pytask_queue.py

      • 成功时:last_status='completed', last_success_at=NOW()
      • 失败时:last_status='failed'last_success_at 不变)
      • 需求: B2.3
    • 8.4 修改 apps/backend/app/routers/schedules.py

      • 创建/更新端点支持新字段写入
      • 列表端点响应包含新字段
      • POST /api/schedules/{id}/run 新增 force: bool = False 查询参数
      • force=false 时检查并发和间隔,不满足返回 409
      • force=true 时绕过所有检查
      • 需求: B3.1, B3.2, B3.3, B3.4, B3.5
  • 9. 编写属性测试 — 模块 B

    • 9.1 创建 tests/test_scheduler_interval_props.py
      • Property 7: 间隔转换正确性 — 生成随机 (value, unit),验证秒数计算正确
      • Property 8: 调度器间隔跳过正确性 — 生成随机任务状态,验证跳过/执行决策
      • Property 9: 调度器并发跳过正确性 — last_status='running' 时跳过
      • Property 10: 强制执行绕过所有检查 — force=true 时无论状态都执行
      • Property 11: last_success_at 仅成功时更新 — 成功更新,失败不变
      • 验证: 需求 B2.1, B2.2, B2.3, B2.4, B3.4
  • 10. 检查点 — 模块 B 后端验证

    • 确保调度器间隔逻辑和 API 扩展所有测试通过ask the user if questions arise.

阶段四ETL 店铺同步(模块 A

  • 11. 后端 — 店铺信息增量同步
    • 11.1 实现同步逻辑(新建 service 或在 admin_registry 路由中实现)

      • 通过 FDW 读取 ETL 库 dwd.dim_sitescd2_is_current=1
      • 对比 biz.sites:新增店铺 INSERTsite_code 留空tenant_id 通过 dim_site.tenant_id 关联 biz.tenants名称/标签变更 UPDATE
      • 不删除已有店铺记录
      • 需求: A5.1, A5.2
    • 11.2 实现手动触发端点

      • POST /api/admin/sites/sync — 手动触发同步,返回同步结果(新增数/更新数)
      • 需求: A5.3
    • 11.3 执行一次初始同步(数据迁移补数据)

      • 在 DDL 迁移(任务 1完成后、代码切换任务 15之前调用同步逻辑补充 auth.site_code_mapping 中没有但 dwd.dim_site 中有的店铺
      • 输出同步结果(新增数/更新数)供验证使用
      • 需求: A1b.1, A1b.2
    • 11.4 预留定时触发入口(随 ETL DWD 完成后通过内部 API 触发)

      • 需求: A5.4

阶段五:前端页面

  • 12. 前端 — 模块 A租户管理员页面重构

    • 12.1 创建 apps/admin-web/src/api/registry.ts

      • 封装 GET /api/admin/tenantsGET /api/admin/tenants/{id}/sites API 调用
      • 封装 PUT /api/admin/sites/{site_id}/site-codeGET /api/admin/sites/{site_id}/site-code-history
      • 封装 POST /api/admin/sites/sync(手动同步)
      • 需求: A4.5
    • 12.2 修改 apps/admin-web/src/api/tenantAdmins.ts

      • 新增 deleteTenantAdmin(id) API 调用
      • 修改 listTenantAdmins 支持 include_inactive 参数
      • 需求: A4.1
    • 12.3 重构 apps/admin-web/src/pages/TenantAdmins/index.tsx

      • 列表页新增「删除」操作按钮Popconfirm 二次确认 → 调用 DELETE API
      • 列表页新增「显示已禁用」Switch 开关
      • 列表页新增「简写ID」操作按钮打开简写ID 管理弹窗)
      • 列表新增「租户」列(显示 tenant_name
      • 编辑弹窗中 username 改为可编辑需校验唯一性409 时提示"用户名已存在"tenant_id 只读
      • 需求: A4.1, A4.3, A2.8
    • 12.4 实现 2 步创建流程

      • 使用 Ant Design Steps 组件
      • 第 1 步选择租户Select数据源 GET /api/admin/tenants→ 输入用户名/密码/显示名称 → 选择管辖门店Select multiple数据源 GET /api/admin/tenants/{id}/sites
      • 第 2 步展示所选租户下所有店铺可为每个店铺设置简写ID可跳过
      • 需求: A4.2
    • 12.5 实现简写ID 管理弹窗

      • Modal 内嵌 Table店铺名称、当前 ID、操作修改
      • 修改行Input + 保存/取消按钮格式校验6 位 3+3
      • 变更历史区域:展示 site_code_history 列表
      • 需求: A4.3, A4.4
  • 13. 前端 — 模块 BScheduleTab 扩展

    • 13.1 修改 apps/admin-web/src/components/ScheduleTab.tsx

      • 创建/编辑表单新增「最小运行间隔」行InputNumber数值+ Select单位分钟/小时/天)
      • 数值为 0 时显示 placeholder "无限制"
      • 位置:在调度类型配置区域下方
      • 需求: B4.1
    • 13.2 修改列表表格

      • 新增「最小间隔」列:显示格式如"10 天"、"1 小时"、"无限制"value=0 时)
      • 新增「上次成功」列:显示 last_success_at 的相对时间dayjs fromNow
      • 需求: B4.2
    • 13.3 修改手动执行确认框

      • 新增 Checkbox「强制执行忽略最小间隔默认不勾选
      • 勾选后调用 POST /api/schedules/{id}/run?force=true
      • 不勾选时调用 POST /api/schedules/{id}/run409 时展示错误提示
      • 需求: B4.3, B4.4
  • 14. 检查点 — 前端页面验证

    • 确保所有前端组件渲染正常API 调用层工作正确ask the user if questions arise.

阶段六:数据迁移与代码切换

  • 15. site_code 查询源切换

    • 15.1 修改 apps/backend/app/routers/tenant_users.py

      • match-suggestions 中的 site_code 查询从 auth.site_code_mapping 切换到 biz.sites + biz.site_code_history
      • 需求: A6.1
    • 15.2 搜索并修改所有其他引用 auth.site_code_mapping 的代码

      • 小程序端用户申请时的 site_code 验证
      • 其他后端路由中的 site_code 查询
      • 需求: A6.1, A6.2
    • 15.3 验证切换后功能正常

      • 用户申请流程中 site_code 查询正确
      • 关联建议匹配正确
      • 需求: A6.3
  • 16. 废弃原表

    • 16.1 验证 biz.sites 数据与 auth.site_code_mapping 一致

      • 编写验证 SQL 对比两表数据
      • 需求: A1.5
    • 16.2 重命名原表为 auth._archived_site_code_mapping

      • 需求: A1.6

阶段七:收尾

  • 17. 数据库变更审计与 DDL 合并

    • 17.1 审计本次实现中对数据库的所有改动
      • 检查新建表biz.connectors/tenants/sites/site_code_history、新增字段scheduled_tasks 三字段、废弃表auth.site_code_mapping
    • 17.2 执行两个迁移脚本到测试库(test_zqyy_app
      • 验证新表和新字段已正确创建(使用 BD 手册中的验证 SQL
    • 17.3 合并到主 DDL 基线文件
      • 模块 A 新表 → docs/database/ddl/zqyy_app__biz.sql
      • 模块 B 新字段 → docs/database/ddl/zqyy_app__public.sql
    • 17.4 验证回滚脚本可执行(任务 1、2 中已编写)
  • 18. BD 手册更新

    • 18.1 创建 docs/database/BD_Manual_biz_registry_tables.md
      • 覆盖 biz.connectors、biz.tenants、biz.sites、biz.site_code_history 四张表
      • 包含:字段明细、约束与索引、验证 SQL≥3 条)、回滚策略
      • 规范: db-docs.md
    • 18.2 更新 docs/database/BD_Manual_tenant_admin_tables.md
      • 补充软删除逻辑说明、tenant_id 从 biz.tenants 选择的变更
    • 18.3 创建/更新 docs/database/BD_Manual_scheduled_tasks.md
      • 新增 min_run_interval_value、min_run_interval_unit、last_success_at 字段说明
      • 包含:字段明细、约束、验证 SQL、回滚策略
  • 19. 前后端联调与集成验证

    • 19.1 启动后端服务,使用测试库验证各端点完整请求-响应链路
      • 验证注册体系 APItenants/sites/site-codeJSON 响应结构与 Schema 定义一致
      • 验证调度器 APIschedules新增字段和 force 参数正常工作
      • 验证权限校验在真实请求中生效
    • 19.2 前端联调验证
      • 确认租户管理员页面能正确调用新增 API 并渲染数据2 步创建、删除、简写ID 管理)
      • 确认 ScheduleTab 扩展字段正确展示和提交
      • 验证空数据/降级场景下前端不崩溃
  • 20. 文档同步更新

    • 20.1 更新后端 API 参考文档
      • apps/backend/docs/API-REFERENCE.md 新增 admin_registry 路由模块文档
      • 更新 schedules 路由模块文档(新增字段和 force 参数)
      • 更新 apps/backend/README.md 路由模块摘要
    • 20.2 更新 admin-web README
      • apps/admin-web/README.md 更新页面说明租户管理员重构、ScheduleTab 扩展)
    • 20.3 更新文档地图
      • docs/DOCUMENTATION-MAP.md 新增本次模块条目BD 手册、Spec
      • 规范: doc-map.md
  • 21. 最终检查点 — 全量验证

    • 运行 Monorepo 属性测试:cd C:\NeoZQYY && pytest tests/ -v
    • 运行后端单元测试:cd apps/backend && pytest tests/ -v
    • 确保所有属性测试Property 1-11和单元测试全部通过
    • 确保 DDL 迁移已合并到主基线
    • 确保 BD 手册已同步更新
    • 确保 API 文档、后端 README、admin-web README、文档地图均已更新
    • 确保前端页面连接真实后端运行正常(租户管理员页面 + ScheduleTab
    • 确保 auth.site_code_mapping 已废弃重命名
    • ask the user if questions arise.
  • 22. 服务清理

    • 22.1 关闭浏览器、停止后端和前端服务、清理资源
      • 停止 uvicorn 后端进程controlPwshProcess stop
      • 停止前端开发服务器controlPwshProcess stop

备注

  • 标记 * 的子任务为可选(属性测试),可跳过以加速 MVP
  • 每个任务引用了具体的需求编号以确保可追溯性A1-A6 对应 NS4.1B1-B4 对应 P16
  • 属性测试验证 11 个正确性属性Property 1-11单元测试验证具体边界条件
  • 检查点任务确保增量验证,避免问题累积(任务 7、10、14、21
  • 模块 A 和模块 B 改动文件无重叠,可交替执行
  • 后端使用 PythonFastAPI + Pydantic + Hypothesis前端使用 TypeScriptReact + Vite + Ant Design
  • 数据迁移采用渐进策略:新建表 → 迁移数据 → 切换代码 → 验证 → 废弃原表
  • 收尾阶段遵循 spec-closing-checklist.md(全栈类 Spec步骤 1-6 全覆盖):
    • 步骤 1最终测试→ 任务 21
    • 步骤 2前后端联调→ 任务 19
    • 步骤 3DDL 合并)→ 任务 17
    • 步骤 4BD 手册)→ 任务 18
    • 步骤 5文档同步→ 任务 20
    • 步骤 6服务清理→ 任务 22