# 会议出勤 Outlook 同步候选性能与筛选修复 Smoke Report

- 日期: 2026-03-04
- 模块: meeting-attendance
- 类型: smoke

## 变更范围
- 修复查询布尔参数解析（`includeCancelled/includePast/onlyUnmanaged/onlyError`）。
- 候选列表读取改为快照优先 + DB 分页，移除请求期 Graph 全量回退。
- 候选系列新增 `seriesChildCount` 返回，列表无需先展开即可展示数量。
- 候选子项接口新增并应用 `includeCancelled/includePast` 筛选。
- 同步页初始化阶段避免首轮重复自动请求。

## 验证命令
```bash
cd backend && npm run build
cd frontend && npm run build
```

## 验证结果
1. 后端构建通过。
2. 前端构建通过。
3. 候选/子项筛选逻辑通过编译链路验证（布尔解析与参数透传）。

## 已知限制
- 本次为构建级 smoke，未在该报告内附带完整账号级 E2E 截图。
- `baseline-browser-mapping` 存在版本过期提示，不影响本次功能构建。

## MCP 页面抽样验证
- 登录账号：`yq.yang@ff.com`（Dev Email Login）。
- 页面：`/meetingattendance/integrations/outlook`。
- 抓取到的接口耗时（Performance API, 近似值）：
  - `GET /integrations/outlook/settings`：约 22ms
  - `GET /integrations/outlook/candidates?page=1&pageSize=20...`：约 32ms
  - `GET /integrations/outlook/bindings?...`：约 34ms
- 结论：候选接口已不再出现秒级阻塞，页面请求链路已恢复到毫秒级。

## MCP 回归补充（本轮）
- 候选为空问题复测：
  - 同账号 `yq.yang@ff.com` 进入同步页，候选列表正常返回，分页显示 `Page 1/3`，非空。
- “包含已取消”筛选复测：
  - 未勾选：候选列表未出现 `Cancelled/已取消` 标签。
  - 勾选后：出现已取消条目，且“纳管”按钮保持禁用。
- 候选链路耗时复测（Performance API）：
  - `GET /integrations/outlook/candidates?page=1&pageSize=20&includeCancelled=false&includePast=false&onlyUnmanaged=false`
  - 连续两次约 `55ms`、`116ms`。
- 结论：
  - 之前 `yq.yang@ff.com` 候选为空问题已修复；
  - 取消筛选行为与交互状态（禁用纳管）符合预期；
  - 候选接口保持毫秒级响应。

## MCP 回归补充（本次续跑）
- 环境修复：
  - 发现后端 `3001` 未启动会导致前端出现 Permission Denied（`/users/me` 连接失败）；启动后恢复正常链路。
- 页面与性能：
  - 登录 `yq.yang@ff.com` 进入 Outlook 同步页，候选列表非空并可分页。
  - `performance` 资源项采样：
    - `GET /integrations/outlook/settings` ≈ 30ms
    - `GET /integrations/outlook/candidates?...` ≈ 64ms
    - `GET /integrations/outlook/bindings?...` ≈ 33ms
- 交互验证：
  - 候选分页 `Page 1 -> Page 2 -> Page 1` 数据正常，无空页回归。
  - 分页后页面滚动位置保持稳定（未跳离候选区，`scrollY` 抽样值保持一致）。
  - 点击“Run Reconcile”可见即时成功 toast：`Reconcile triggered and data refreshed`。
  - 同步设置新增开关 `Include organizer as attendee (optional)` 可保存并 toast 成功，复位后再次保存成功。
- 筛选行为：
  - 未勾选 `Include cancelled` 时，页面未出现取消标签（抽样 `body.innerText` 检查）。
  - 候选类型过滤 `Series Master` + `Include past meetings` 在当前窗口下可返回空集，表现为 `No data`（与筛选口径一致）。
