## MODIFIED Requirements ### Requirement: TanStack Query 数据层 前端 SHALL 使用 TanStack Query(@tanstack/react-query)管理所有 API 请求,数据层代码 SHALL 按职责拆分为独立 hook 文件。 #### Scenario: QueryClient 配置 - **WHEN** 应用启动 - **THEN** 系统 SHALL 创建 QueryClient,默认配置 retry=1、refetchOnWindowFocus=true、staleTime=5000 #### Scenario: QueryClientProvider 挂载 - **WHEN** 应用渲染 - **THEN** 根组件 SHALL 包裹在 QueryClientProvider 中,提供 QueryClient 实例 ### Requirement: queryKey 工厂 系统 SHALL 提供统一的 queryKey 工厂函数,确保 queryKey 的唯一性和一致性。 #### Scenario: summary queryKey - **WHEN** 查询 summary 数据 - **THEN** queryKey SHALL 为 ["summary"] #### Scenario: targets queryKey - **WHEN** 查询 targets 数据 - **THEN** queryKey SHALL 为 ["targets"] #### Scenario: meta queryKey - **WHEN** 查询 meta 数据 - **THEN** queryKey SHALL 为 ["meta"] #### Scenario: trend queryKey - **WHEN** 查询某目标的趋势数据 - **THEN** queryKey SHALL 为 ["trend", targetId, from, to] #### Scenario: history queryKey - **WHEN** 查询某目标的历史记录 - **THEN** queryKey SHALL 为 ["history", targetId, from, to, page] ### Requirement: Hook 文件拆分 数据层 hook SHALL 按职责拆分为独立文件。 #### Scenario: 全局查询 hook 文件 - **WHEN** 开发者需要使用全局面板级查询 - **THEN** `useSummary`、`useTargets`、`useMeta` SHALL 从 `hooks/use-queries.ts` 导出 #### Scenario: Drawer 状态 hook 文件 - **WHEN** 开发者需要使用 Drawer 状态管理 - **THEN** `useTargetDetail` SHALL 从 `hooks/use-target-detail.ts` 导出 #### Scenario: fetchJson 不导出 - **WHEN** 数据层内部需要 fetch 封装 - **THEN** `fetchJson` SHALL 定义在 `use-queries.ts` 内部,不作为公共 API 导出 #### Scenario: queryKeys 不导出 - **WHEN** 数据层内部需要 query key - **THEN** `queryKeys` 对象 SHALL 定义在 `use-queries.ts` 内部,不作为公共 API 导出 ### Requirement: Meta 查询 系统 SHALL 提供 `useMeta` hook 查询系统元数据。 #### Scenario: meta 查询配置 - **WHEN** 应用启动 - **THEN** `useMeta` SHALL 请求 `/api/meta`,配置 `staleTime: Infinity`(应用生命周期内只请求一次) #### Scenario: meta 数据返回 - **WHEN** meta 查询成功 - **THEN** hook SHALL 返回 `MetaResponse` 类型数据,包含 `checkerTypes` 字段 ### Requirement: Summary 轮询查询 系统 SHALL 使用 useQuery 实现总览统计的自动轮询。 #### Scenario: summary 自动轮询 - **WHEN** Dashboard 页面处于打开状态 - **THEN** 系统 SHALL 每 8 秒自动请求 /api/summary,使用 refetchInterval=8000 #### Scenario: summary 后台刷新 - **WHEN** 页面处于后台标签页 - **THEN** 系统 SHALL 暂停轮询(refetchIntervalInBackground=false) ### Requirement: Targets 轮询查询 系统 SHALL 使用 useQuery 实现目标列表的自动轮询。 #### Scenario: targets 自动轮询 - **WHEN** Dashboard 页面处于打开状态 - **THEN** 系统 SHALL 每 8 秒自动请求 /api/targets,使用 refetchInterval=8000 ### Requirement: 条件查询 趋势和历史记录查询 SHALL 使用 enabled 条件控制,仅在目标被选中时触发。 #### Scenario: 未选中目标时不请求 - **WHEN** 用户未点击任何目标表格行 - **THEN** trend 和 history 的 useQuery SHALL enabled=false,不发起请求 #### Scenario: 选中目标时自动请求 - **WHEN** 用户点击目标表格行 - **THEN** trend 和 history 的 useQuery SHALL enabled=true,自动发起请求 #### Scenario: 时间范围变化时重新请求 - **WHEN** 用户更改时间范围 - **THEN** trend 和 history 的 useQuery SHALL 因 queryKey 变化自动重新请求 ### Requirement: 开发调试面板 开发环境下 SHALL 挂载 TanStack Query Devtools。 #### Scenario: 开发环境显示 Devtools - **WHEN** 应用在开发模式下运行 - **THEN** 页面 SHALL 显示 ReactQueryDevtools 浮动面板 #### Scenario: 生产环境排除 Devtools - **WHEN** 应用在生产模式下构建 - **THEN** ReactQueryDevtools SHALL 不被包含在产物中