Files
Neo-ZQYY/docs/specs/admin-web-enhancement/requirements.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

182 lines
12 KiB
Markdown
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.
# 需求文档 — NS4.1 + P16Admin-Web 管理后台增强
## 简介
本 Spec 合并两个独立需求NS4.1(租户管理员页面重构 + 项目级注册体系)和 P16调度任务最小运行间隔机制。两者均为 admin-web 管理后台的功能增强,改动文件无重叠,合并执行以减少上下文切换。
### 合并理由
- 两者都是 admin-web 后台功能迭代,共享同一前端项目(`apps/admin-web/`)和后端项目(`apps/backend/`
- NS4.1 改动集中在租户管理员页面(`TenantAdmins/`+ 新建注册体系路由P16 改动集中在调度任务页面(`ScheduleTab.tsx`+ 调度器逻辑
- 改动文件完全不重叠,合并不增加冲突风险
- 共享收尾流程DDL 合并、BD 手册、文档同步)
### 依赖
- NS4租户管理后台基础设施`tenant-admin-web` spec 已完成
- P3用户认证体系`03-miniapp-auth-system` spec 已完成
### 来源文档(权威参考)
实施过程中如遇细节不明确,应优先查阅以下 PRD 原文:
- `docs/prd/Neo_Specs/NS4.1-tenant-admin-redesign.md` — NS4.1 PRD 主文档(数据模型 DDL、页面布局、接口设计、迁移步骤、边界条件
- `docs/prd/specs/P16-task-min-run-interval.md` — P16 PRD 主文档调度器逻辑、API 扩展、前端变更、边界条件)
### 不在本 spec 范围
- P15AI 监控后台 + 测试重建 + 回填)— 单独 Spec
- 多连接器完整实现(仅预留 `biz.connectors` 表结构)
- `dwd.dim_site` 物理迁移(保留在 `dwd` schema
- 租户管理员自助注册
- 简写ID 自动生成
- ETL 任务注册机制修改(`TaskMeta`/`TaskRegistry`
- 批量 seed SQL 设定初始间隔值
## 术语表
- **admin-web**:系统管理后台(`apps/admin-web/`),面向系统管理员
- **tenant-admin**:租户管理后台(`apps/tenant-admin/`),面向租户管理员
- **biz.connectors**:连接器注册表,记录接入的上游 SaaS 系统
- **biz.tenants**:租户注册表,连接器下的租户
- **biz.sites**:店铺注册表,合并原 `auth.site_code_mapping`
- **biz.site_code_history**简写ID 变更历史表
- **site_code**店铺简写ID6 位字符3+3 格式,如 `LLQ001`
- **min_run_interval**:调度任务最小运行间隔,任务开始执行后的最小等待时间
- **scheduled_tasks**:调度任务表(`public.scheduled_tasks`),存储 ETL 调度配置
- **scheduler.py**:调度器核心逻辑,每 30 秒轮询到期任务
## 需求
### 模块 ANS4.1 — 租户管理员页面重构 + 项目级注册体系
#### 需求 A1项目级注册体系 — 连接器/租户/店铺三级表
**用户故事:** 作为系统管理员,我希望建立「连接器 → 租户 → 店铺」三级注册体系,以便统一管理上游 SaaS 系统、租户和店铺的关系并为简写ID 提供归属。
##### 验收标准
1. THE Backend SHALL 在 `biz` schema 新建 `connectors`id, connector_key UNIQUE, display_name, is_active, created_at初始数据插入 `('feiqiu', '飞球')`
2. THE Backend SHALL 在 `biz` schema 新建 `tenants`id, connector_id FK, tenant_id BIGINT, tenant_name, is_active, created_at, updated_atUNIQUE(connector_id, tenant_id)
3. THE Backend SHALL 在 `biz` schema 新建 `sites`id, tenant_id FK, site_id BIGINT UNIQUE, site_name, site_code VARCHAR(6) UNIQUE, site_label, is_active, created_at, updated_at
4. THE Backend SHALL 在 `biz` schema 新建 `site_code_history`id, site_id BIGINT, site_code VARCHAR(6) UNIQUE, is_current BOOLEAN, created_at, retired_at
5. THE Backend SHALL 将 `auth.site_code_mapping` 中真实数据(`tenant_id IS NOT NULL`)迁移到 `biz.sites`,并为已有 `site_code` 创建 `site_code_history` 记录(`is_current=true`
6. THE Backend SHALL 在迁移完成并验证后,将 `auth.site_code_mapping` 重命名为 `auth._archived_site_code_mapping`
#### 需求 A1b数据迁移后初始同步
**用户故事:** 作为系统管理员,我希望迁移完成后立即运行一次 ETL 同步,补充 `biz.sites` 中缺失的店铺(`dwd.dim_site` 中有但 `auth.site_code_mapping` 中没有的),确保注册体系数据完整。
##### 验收标准
1. THE Backend SHALL 在数据迁移A1完成后、代码切换A6之前执行一次店铺同步复用 A5 的同步逻辑),将 `dwd.dim_site``scd2_is_current=1`)中存在但 `biz.sites` 中不存在的店铺补充插入
2. THE Backend SHALL 在初始同步完成后输出同步结果(新增数/更新数),供验证使用
#### 需求 A2租户/店铺管理 API
**用户故事:** 作为系统管理员,我希望通过 API 查询租户列表和店铺列表,以便在创建管理员时选择所属租户和管辖门店。
##### 验收标准
1. THE Backend SHALL 实现 `GET /api/admin/tenants` 端点,返回所有活跃租户(含连接器名称)
2. THE Backend SHALL 实现 `GET /api/admin/tenants/{tenant_id}/sites` 端点,返回指定租户下所有活跃店铺(含当前 site_code
3. THE Backend SHALL 实现 `DELETE /api/admin/tenant-admins/{id}` 端点,软删除管理员(`is_active=false`
4. THE Backend SHALL 实现 `PUT /api/admin/sites/{site_id}/site-code` 端点,设置/修改店铺简写ID
5. THE Backend SHALL 实现 `GET /api/admin/sites/{site_id}/site-code-history` 端点查看简写ID 变更历史
6. THE Backend SHALL 修改 `POST /api/admin/tenant-admins` 端点,创建时 `tenant_id``biz.tenants` 选择,`managed_site_ids``biz.sites` 选择
7. THE Backend SHALL 修改 `GET /api/admin/tenant-admins` 端点,默认只返回 `is_active=true`,增加 `include_inactive` 参数
8. THE Backend SHALL 修改 `PATCH /api/admin/tenant-admins/{id}` 端点,支持修改 `username`(需校验全局唯一性,冲突返回 409
#### 需求 A3简写ID 管理逻辑
**用户故事:** 作为系统管理员我希望在管理后台设置和修改店铺简写ID并保留变更历史以便保护已提交但未审核的用户申请。
##### 验收标准
1. WHEN 修改简写ID 时THE Backend SHALL 在事务内执行:旧 code 标记 `is_current=false` + `retired_at=NOW()`,新 code 插入 `site_code_history``is_current=true`),更新 `biz.sites.site_code`
2. THE Backend SHALL 校验新 code 格式6 位3+3 模式,统一大写存储)和全局唯一性(含 `biz.sites.site_code` + `biz.site_code_history.site_code`
3. WHEN 旧 code 有未审核申请引用(`auth.user_applications WHERE site_code = :old_code AND status = 'pending'`THE Backend SHALL 保留历史记录不删除
4. WHEN 旧 code 无任何申请引用时THE Backend SHALL 从 `biz.site_code_history` 中删除该条记录
#### 需求 A4租户管理员页面重构admin-web
**用户故事:** 作为系统管理员,我希望在 admin-web 中通过改进的界面管理租户管理员,支持 2 步创建流程、软删除和简写ID 管理。
##### 验收标准
1. THE admin-web SHALL 重构租户管理员列表页,新增「删除」操作按钮(二次确认 → 软删除),默认只显示活跃记录,可选「显示已禁用」开关
2. THE admin-web SHALL 实现 2 步创建流程:第 1 步选择租户(下拉 `biz.tenants`+ 输入账号信息 + 选择管辖门店(`biz.sites`);第 2 步可选设置简写ID
3. THE admin-web SHALL 在编辑弹窗中增加「管理简写ID」区域展示该租户下所有店铺及其当前 code支持修改编辑时所属租户`tenant_id`)为只读不可修改;用户名(`username`)可修改(需校验唯一性)
4. THE admin-web SHALL 新增简写ID 管理弹窗,展示变更历史,支持修改操作
5. THE admin-web SHALL 新增 `src/api/registry.ts` 封装租户/店铺列表 API 调用
#### 需求 A5ETL 店铺信息增量同步
**用户故事:** 作为系统管理员,我希望 ETL 完成后能自动同步店铺信息到业务库,以便 `biz.sites` 中的店铺名称和标签保持最新。
##### 验收标准
1. THE Backend SHALL 实现店铺同步逻辑:通过 FDW 读取 ETL 库 `dwd.dim_site``scd2_is_current=1`),对比 `biz.sites`,新增店铺 INSERT`site_code` 留空),名称/标签变更 UPDATE
2. THE Backend SHALL 不删除已有店铺记录(即使上游标记为关闭)
3. THE Backend SHALL 支持手动触发同步(管理后台按钮或 API 端点)
4. THE Backend SHALL 支持定时触发同步(随 ETL 日常调度DWD 层完成后通过内部 API 触发)
#### 需求 A6后端代码切换 — site_code 查询源
**用户故事:** 作为后端开发者,我希望所有读取 `auth.site_code_mapping` 的代码切换到 `biz.sites` + `biz.site_code_history`,以便完成数据迁移。
##### 验收标准
1. THE Backend SHALL 将所有读取 `auth.site_code_mapping` 的查询切换到 `biz.sites`
2. THE 小程序端 SHALL 将用户申请时的 `site_code` 查询从 `auth.site_code_mapping` 切换到 `biz.sites` + `biz.site_code_history`
3. THE Backend SHALL 确保切换后所有现有功能(用户申请、关联建议匹配等)正常工作
---
### 模块 BP16 — 调度任务最小运行间隔机制
#### 需求 B1scheduled_tasks 表扩展
**用户故事:** 作为管理员,我希望为每个调度任务设置最小运行间隔,使任务即使调度到期也不会在间隔内重复执行。
##### 验收标准
1. THE Backend SHALL 在 `scheduled_tasks` 表新增 `min_run_interval_value`INTEGER DEFAULT 0`min_run_interval_unit`VARCHAR(20) DEFAULT 'minutes')、`last_success_at`TIMESTAMPTZ NULL3 个字段
2. THE Backend SHALL 确保 `min_run_interval_value = 0` 表示无限制,与现有行为完全一致(向后兼容)
#### 需求 B2调度器核心逻辑 — 并发检查 + 间隔检查
**用户故事:** 作为管理员,我希望调度器在轮询时自动检查最小间隔和并发状态,避免任务重复执行或并发执行。
##### 验收标准
1. THE scheduler SHALL 在 `check_and_enqueue()` 中新增并发检查:若 `last_status = 'running'`,跳过本次入队,日志记录 `skipped_concurrent`
2. THE scheduler SHALL 在 `check_and_enqueue()` 中新增间隔检查:若 `min_run_interval_value > 0``now() - last_run_at < min_interval_seconds`,跳过本次执行并推进 `next_run_at`,日志记录 `skipped_interval`
3. WHEN `last_run_at IS NULL`从未执行THE scheduler SHALL 跳过间隔检查,正常执行
4. THE scheduler SHALL 在任务成功完成时同时更新 `last_success_at = NOW()`,失败时不更新 `last_success_at`
5. THE scheduler SHALL 实现 `_convert_interval_to_seconds(value, unit)` 辅助函数,支持 `minutes`/`hours`/`days` 单位
#### 需求 B3API 扩展 — 创建/更新/手动执行
**用户故事:** 作为管理员,我希望通过 API 配置最小运行间隔,并在必要时强制执行任务。
##### 验收标准
1. THE Backend SHALL 在 `POST /api/schedules``PUT /api/schedules/{id}` 端点的请求体中新增 `min_run_interval_value`int, default=0`min_run_interval_unit`str, default='minutes'
2. THE Backend SHALL 在 `GET /api/schedules` 响应中新增 `min_run_interval_value``min_run_interval_unit``last_success_at` 字段
3. THE Backend SHALL 在 `POST /api/schedules/{id}/run` 端点新增 `force: bool = False` 查询参数
4. WHEN `force=true`THE Backend SHALL 绕过最小间隔和并发检查,直接入队执行
5. WHEN `force=false` 且间隔未到时THE Backend SHALL 返回 409 Conflict提示"最小运行间隔未到,距下次可执行还有 X 分钟"
6. WHEN `force=false` 且任务正在运行时THE Backend SHALL 返回 409 Conflict提示"任务正在执行中"
#### 需求 B4Admin Web 前端 — ScheduleTab 扩展
**用户故事:** 作为管理员,我希望在调度任务管理界面中看到和配置最小运行间隔。
##### 验收标准
1. THE admin-web SHALL 在创建/编辑调度任务表单中新增「最小运行间隔」行:`InputNumber`(数值)+ `Select`(单位:分钟/小时/天),数值为 0 时显示提示"无限制"
2. THE admin-web SHALL 在任务列表表格中新增「最小间隔」列(显示如"10 天"、"无限制")和「上次成功」列(相对时间)
3. THE admin-web SHALL 在手动执行确认框中新增「强制执行(忽略最小间隔)」勾选项,默认不勾选
4. WHEN 勾选强制执行时THE admin-web SHALL 调用 `POST /api/schedules/{id}/run?force=true`