Skip to content

feat(frontend): Ant Design Pro SPA migration (P0–P5 + review fixes) - #109

Merged
ZeroPointSix merged 185 commits into
mainfrom
feat/ant-design-pro-frontend-migration
Aug 17, 2026
Merged

feat(frontend): Ant Design Pro SPA migration (P0–P5 + review fixes)#109
ZeroPointSix merged 185 commits into
mainfrom
feat/ant-design-pro-frontend-migration

Conversation

@ZeroPointSix

Copy link
Copy Markdown
Owner

Summary

  • 将管理端前端逐步迁移到 ant-design-pro/(Ant Design Pro + React 19 + Umi Max),与 Flask 后端通过 session cookie + CSRF 对接
  • 完成 P0–P5 业务页:概览 / 账号分组 / 邮件 / 临时邮箱与插件 / 设置·审计·邮箱池·Token 工具·刷新日志
  • 审查修复:pool-admin 契约对齐(items/totalin_pool=true|false|all、动作名)、/token-tool 代理收敛、HTTP 错误体规范化、设置敏感字段脱敏 UX
  • 已与 origin/main 合并(含邮箱池临时邮箱 claim、gunicorn 并发修复等)

部署联调建议

  1. 后端:python start.py(或现有 Docker/Gunicorn)
  2. 前端:cd ant-design-pro && npm install && npm start(代理到 :5000
  3. 生产:npm run build,网关反代 /api /login /logout /img /healthz,SPA fallback 到 index.html
  4. 契约回归:
    python -m unittest tests.test_auth_spa_adapters tests.test_overview_api_contract tests.test_accounts_groups_api_contract tests.test_emails_api_contract tests.test_temp_emails_plugins_api_contract tests.test_p5_api_contract -v

Test plan

  • 迁移契约套件 41/41 通过(合并 origin/main 后复跑)
  • 双进程冒烟:登录 → 概览 → 账号/分组 → 邮件列表详情 → 临时邮箱 → 邮箱池动作 → 设置敏感字段保存
  • Token 工具:准备 → 授权链接 → 回调粘贴 → 写回账号
  • 确认 SPA /token-tool 不被代理抢走;业务 API 走 /api/token-tool/*
  • 生产构建 npm run build + 网关反代 cookie/CSRF 正常

ZeroPointSix and others added 10 commits July 10, 2026 18:28
引入 ant-design-pro 作为与 outlook_web 平级的前端工程,完成 Flask
session/CSRF 鉴权适配与业务路由骨架,作为按功能迁移的基础设施。

- 后端新增 /api/auth/current-user、/api/auth/logout,兼容旧 /logout
- 前端 proxy 到 Flask,统一 credentials + CSRF 请求封装
- 登录页改为单密码;菜单对齐旧侧栏功能模块
- 补充 SPA 鉴权适配单测(含对抗用例)
将旧 dashboard 的五个概览 Tab 迁到 /overview:
- services/outlook/overview 对接 /api/overview/*
- 按 Tab 懒加载(react-query useQuery)
- KPI / 进度 / 表格展示账号、验证码、对外 API、邮箱池、活动
- 补充 overview API 契约测试与 utils 单测
将账号/分组管理迁入 Ant Design Pro:
- services/outlook/accounts|groups 对接列表、创建、更新、删除
- /groups:ProTable + ModalForm CRUD,过滤临时邮箱系统组
- /accounts:分页搜索、分组筛选、删除与跳转邮箱
- 补充 accounts/groups API 契约测试(含重名对抗)
对接 /api/emails 与 /api/email 详情链路:账号选择、文件夹切换、列表/详情双栏、502 错误 details 展示、批量删除。补充邮件 API 契约测试(登录鉴权、404、全链路失败结构、成功字段形状)。
临时邮箱三栏工作区(生成/列表/消息/详情)对接 /api/temp-emails/*;插件管理对接安装/卸载/配置/连接测试/应用变更。补充 P4 API 契约测试。
完成设置 Tabs、审计日志、邮箱池管理、OAuth Token 工具与刷新日志页面迁移;补充对应 service 层与 P5 API 契约测试。
Align SPA pool filters/actions with backend true|false|all and ACTION_RULES,
narrow /token-tool proxy to OAuth callback only, normalize HTTP error bodies
in outlookRequest, and harden P5 contract tests.
Support masked secret fields on settings page (skip unchanged masks on
save), document production build/proxy cutover, and list residual SPA gaps.
Bring remote pool/gunicorn/docs updates into the Ant Design Pro migration branch before opening the PR.
Login succeeds but post-auth layout crashes with ReferenceError: Link is not defined because menuItemRender uses <Link> without importing it from @umijs/max.
@ZeroPointSix

Copy link
Copy Markdown
Owner Author

UAT 部署结果(并行环境)

机器do-64-227-openhands(低负载并行 UAT,未动线上 do-nyc-001
提交b94fbfa(含部署中发现的前端修复)

访问地址

部署形态

  • 后端:Docker outlook-email-plus-pr109(healthy),宿主机 127.0.0.1:15001
  • 前端:Ant Design Pro SPA build → Caddy 反代 /api/login 等到 Flask,其余走 dist + SPA fallback

冒烟结果

检查 结果
/healthz 200 status=ok version 2.7.0
CSRF + /login 200 登录成功
/api/auth/current-user 200 admin
/api/overview/summary 200 KPI 结构正常(空数据环境)
SPA 路由 /overview 200
浏览器登录后布局 侧栏菜单 + Overview 卡片正常,无 JS error

部署中修的问题

登录后布局崩溃:ReferenceError: Link is not defined
原因:ant-design-pro/src/app.tsxmenuItemRender 用了 <Link> 但未从 @umijs/max 导入。
已推送修复提交:b94fbfa fix(frontend): import Link for ProLayout menuItemRender,UAT 已重建并验证通过。

UAT 登录密码

部署时生成的随机密码见 VPS:/srv/outlook-email-plus-pr109/.login-password.txt(或问部署人)。当前实例密码:80z3lxLoJvcWomcf

@cursor

cursor Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

对抗式功能审查:旧前端 vs PR #109 SPA(只审查,不改代码)

对比对象

  • 旧:https://outlook.137-184-23-118.sslip.io/templates/ + static/js/features/*
  • 新:https://outlook-pr109.64-227-13-213.sslip.io/ant-design-pro/ @ b94fbfa
  • 方法:代码 1:1 对照 + 新 UAT API 冒烟(登录/CSRF/各业务 API);旧站无可用密码,未做登录后浏览器点验

总结论(功能视角)

当前 SPA 不能作为旧管理端的 1:1 平替。
路由骨架与主链路 API 已打通(P0–P5),但大量核心运维能力缺失;另有若干契约映射错误会导致页面“看起来有、实际空白/恒失败”。README 自称的残余差距偏乐观、不完整

建议:在补齐下方 P0 缺陷 + P0 能力缺口 前,不要切默认流量到 SPA。


模块完成度(主观)

模块 完成度 一句话
登录 / 鉴权 ~80% 能登录;logo 破图、占位文案 Password: ant.design、Footer 仍指向 ant-design-pro 上游
概览 ~85% 前 4 Tab 较完整;系统活动 Tab 半成品(未读 timeline / notification_stats
账号 ~25% 仅列表/删/跳邮件;无导入/编辑/批量/标签/导出/Token 刷新/通知开关
分组 ~60% 基础 CRUD;缺验证码策略字段;删除文案与后端不符
邮件 ~45% 能拉信/详情/批量删;无验证码提取、无轮询、无三栏工作台、HTML 安全模型弱化
临时邮箱 ~80% 三栏较完整;domain_strategy / formatted 验证码弱于旧版
插件 ~55% 列表/安装有;配置 schema 路径错误 → 配置弹窗恒空
设置 ~55% 骨架在;多 Key / IP 白名单 / CF 同步 / 临时邮箱完整配置 / 部署更新入口缺失;Cron 校验参数名错误
邮箱池 ~70% 单条动作可用;无批量、无 Provider 筛选、claimed 态动作未裁剪
Token 工具 ~75% 主流程可用;指引/Scope 预设/全字段复制缩水;默认 Scope 与旧版不同
审计 ~70% 表结构在,但列名 detail/ip 对不上后端 details/user_ip
刷新日志 ~65% 列名 email/message 对不上 account_email/error_message;「失败」语义≠全量失败过滤

P0 — 必须先修的缺陷(实现有问题)

  1. 插件配置表单解析路径错误

    • SPA:schemaRes?.data?.fieldsconfigRes?.dataant-design-pro/src/pages/plugins/index.tsx
    • 后端:data.config_schema.fields / data.configtemp_mail_plugin_manager.py
    • 结果:已安装插件「配置」几乎恒显示「无可配置字段」
  2. Cron 校验请求体字段名错误

    • SPA:{ cron }services/outlook/settings.ts validateCron
    • 后端:只认 cron_expressioncontrollers/settings.py
    • 结果:校验按钮恒失败
  3. 审计 / 刷新日志列字段映射错误

    • 审计:UI detail/ip vs API details/user_ip(另缺 trace_id
    • 刷新日志:UI email/message vs API account_email/error_message
    • 结果:有数据时邮箱/详情/IP 列常显示 --
  4. 概览「系统活动」未绑定后端真实字段

    • API 返回 kpi + notification_stats + timeline
    • SPA ActivityPanerecent/items(不存在)→ Tab 实质空白
  5. 分组删除文案错误

    • UI:仅空分组可删除
    • 后端:删除时迁移账号到默认分组,不要求空分组

P0 — 旧有、新缺的核心能力(功能缺口)

  1. 账号导入 / 添加 / 编辑(多 Provider、auto 智能分组、入池、IMAP 差异表单)
    • createAccount 已在 service 封装,页面未调用;无编辑入口
  2. 验证码提取工作流(账号卡一键复制、邮件详情提取、/api/emails/{email}/extract-verification
    • mailbox 页完全无此能力(仅 temp-emails 有提取)
  3. 自动轮询监听poll-engine.js + 设置项 + 选中账号启动)
    • SPA 无轮询引擎
  4. 三栏 mailbox 工作台(分组→账号→邮件一条流)
    • 拆成 /groups /accounts /mailbox,无法同屏完成主路径
  5. 设置:外部 API 多 Key 表格(README 已承认)+ 临时邮箱 Provider/域名/前缀完整配置 + CF Worker 域名同步

P1 — 重要运维降级

  • 批量:打标签 / 移组 / 批量拉信 / 通知开关 / 刷新 Token / 批量删除
  • 标签管理与按标签筛选
  • Token 全量/选中刷新(含 SSE)、账号导出(二次验证)
  • 通知参与开关、简洁模式、分组级验证码策略字段
  • 邮箱池批量移入移出、Provider 筛选、claimed 态动作裁剪
  • 设置:IP 白名单、disable raw/wait/pool 子开关、部署警告、trigger-update
  • Token 工具:Azure 指引、Scope chips、结果全字段 + 一键复制
  • 业务页 i18n(旧双语 vs SPA 中文硬编码)

逻辑不一致(抽样)

风险
账号默认排序 refresh_time asc 写死 email 运维找问题号习惯失效
mailbox 账号范围 先选组再拉账号 全局 page_size=200 无分页 大实例选不到账号
切文件夹 先缓存/提示再手动获取 useEffect 立即请求 请求更激进
邮件 HTML DOMPurify + 信任模式 + cid 重写 iframe sandbox="" + 原始 HTML 渲染/安全策略不同
Token 默认 Scope offline_access + Graph .default Mail.Read offline_access openid profile 首次授权范围不同
临时邮箱系统组判定 按名称 额外 is_system===1 语义过宽隐患
刷新日志「失败」 全量列表 /refresh-logs/failed(每账号最近一次失败) UI 字面语义易误解

API 面缺口(旧前端有调用、SPA 未接入,节选)

/api/accounts/batch-*/api/accounts/refresh/selected/api/accounts/export-selected/api/export/verify/api/accounts/tags/api/providers/api/extract-verification/api/emails/batch/api/settings/cf-worker-sync-domains/api/system/deployment-info/api/system/trigger-update/api/bootstrap 等。


README.outlook.md「残余差距」核对

已写到的:多 Key、布局拖拽/compact poll、旧 templates 保留 — 准确但不够
漏报应补:活动 Tab 回归、审计/刷新日志字段映射、插件 schema 路径、Cron 参数、账号 CRUD/验证码/轮询/三栏工作台、设置大块缺失、池批量、Token 指引、业务 i18n。


验收建议优先级(仍不改代码,仅建议)

  1. 先修 P0 缺陷:插件 config 路径、Cron 参数、审计/刷新日志列名、活动 Tab、分组删除文案
  2. 再补 P0 能力:账号导入编辑、验证码、轮询(或明确砍掉并改产品口径)、设置多 Key + 临时邮箱完整配置
  3. 然后做运维 parity:批量/标签/Token 刷新/导出/池批量
  4. 更新 README 残余差距表,避免「P5 已勾选」掩盖回归

审查人:Cursor Cloud Agent(对抗式功能审查,未提交代码变更)
对照提交b94fbfa

@ZeroPointSix

Copy link
Copy Markdown
Owner Author

PR #109 合并前修复清单与优先级排序(对抗式 1:1 审查结论)

审查方式:现有 Flask 管理端(templates/ + static/js/features/ + main.js 等 ~15k 行)与新 ant-design-pro/ SPA 逐功能点 1:1 对抗式比对。每条均附 file:line 证据,关键项经「对抗怀疑者」直接复核源码确认。

总体判断

迁移未达合并标准。UAT 冒烟(登录/概览/列表渲染)能过,但冒烟覆盖不到下列功能缺口——其中 P0 项会导致审计页 3/7 列空白、核心「收验证码」用例失效、账号无法增改。建议阻塞合并,先修 P0


🔴 P0 — 合并阻塞(不修不能合)

1. 审计页字段契约错配,7 列中 3 列永久空白

  • ant-design-pro/src/pages/audit/index.tsx:45 dataIndex:'detail' → 后端返回 detailsoutlook_web/audit.py:91)→ 详情列恒为 --
  • audit/index.tsx:59 dataIndex:'ip' → 后端返回 user_ipaudit.py:90)→ IP 列恒为 --
  • audit/index.tsx:52 dataIndex:'operator' → 后端 audit.py:70/29 根本不返回此字段 → 虚构列恒为 --
  • 服务类型 services/outlook/audit.ts:8-10 三处字段名全错;[key:string]:any 索引签名掩盖了 TS 编译期检查
  • 基线对照:static/js/main.js:3815log.details:3825log.user_ip——基线正确
  • 修复:服务类型改 details/user_ip、删 operator 列(或后端补字段)、列 dataIndex 同步;移除索引签名以让 TS 兜底

2. 验证码提取功能完全缺失(核心用例)

  • 基线:emails.js:829 extractVerificationFromDetail:367 extractVerificationFallbackFromDetail:1028 copyEmailmailbox_compact.js:143 copyCompactVerification:361 buildDetailVerificationOptions
  • 新:mailbox/index.tsx:449-466 仅把 detail.body 塞进 iframe,无任何验证码提取/一键复制入口
  • 影响:本工具核心场景是「收验证码」,新 UI 下用户必须肉眼找码手动复制——功能性倒退
  • 修复:迁移 extractVerificationFromDetail 逻辑 + 邮件详情区加「复制验证码」按钮

3. 账号管理只剩「列表+删除」,无增/改

  • 基线 accounts.js(905 行):showAddAccountModal/addAccount(多 provider 建号)、showEditAccountModal/updateAccount(编辑)、showEditRemarkOnly(速改备注)
  • accounts/index.tsx(231 行):仅 list + email 搜索 + 分组筛选 + 删除(:126-161)。无创建按钮、无编辑
  • 修复:补「添加账号」模态(含 provider 选择)+ 「编辑账号」模态

4. 轮询引擎丢失,但设置页保留死配置

  • 基线:poll-engine.js(346 行)+ mailbox_compact.js:510 startCompactAutoPoll:387 updateCompactPollUImain.js:349 applyPollingSettings——按账号自动轮询新邮件 + 实时 UI 指示
  • 新:所有业务页无任何 setInterval/轮询;但 settings/index.tsx:62-64,244-258 仍保留 enable_auto_polling/polling_interval/polling_count 配置项
  • 影响:用户配的轮询参数不生效,是欺骗性 UX
  • 修复(二选一):补回轮询引擎(推荐,配合邮箱页实时收信);或暂时从设置页移除轮询配置项并在 README 标注「待迁移」

🟡 P1 — 合并后立即跟进(建议本 PR 内修)

5. 邮箱 iframe 全锁死,无信任切换

  • mailbox/index.tsx:457 sandbox="" 完全锁死,合法邮件外部图片/样式被挡且无逃生口
  • 基线 emails.js:911 toggleTrustMode 提供信任切换 + :845 openFullscreenEmail 全屏
  • 修复:加「信任此发件人/显示外部内容」开关,或改用 DOMPurify(基线即用 dompurify CDN)替代纯 sandbox

6. i18n 国际化回归

  • 基线 i18n.js(1,552 行)全量 zh/en
  • 新业务页全部硬编码中文:accounts/index.tsx:137overview/index.tsx:351settings/index.tsx:255mailbox/index.tsx:331audit/index.tsx:18,68,75,101,111 等。仅 Admin.tsx/exception/404useIntl
  • LangDropdown 组件已接(app.tsx:101)但业务页不支持——架构自相矛盾
  • 修复:业务页接入 useIntl().formatMessage,补 src/locales/*/settings.ts 消息 id

7. 内联图片(CID)重写丢失

  • 基线 emails.js:620 rewriteEmailInlineImages:600 normalizeEmailInlineResourceKey:613 resolveEmailInlineResource
  • mailbox/index.tsx:230 直接输出 detail.body,CID 内联图片无法渲染
  • 修复:迁移 CID 重写逻辑

8. 账号管理其余功能缺口

  • toggleAccountStatus(启停)、toggleTelegramPush(Telegram 推送开关)、batchNotificationToggle(批量通知)、showExportModal/exportSelectedGroups/confirmExportVerify(导出)、导入处理 refreshMailboxAfterImport——新页全无
  • 修复:补状态切换、Telegram 开关、导入导出

9. 邮箱 URL 状态不完整

  • mailbox/index.tsx:199?account= 入 URL,folder/skip 不入 → 刷新丢文件夹上下文
  • 修复:folder + skip 同步到 URL

10. 邮箱排序/筛选缺失

  • 基线 emails.js:12 sortEmailsByNewestFirst:207 updateEmailBatchActionBar
  • 新页无客户端排序、无已读/未读筛选、无箱内搜索
  • 修复:补排序 + 已读筛选

⚪ P2 — 后续优化(可独立 PR)

# 问题 证据
11 邮箱紧凑视图模式丢失 基线 mailbox_compact.js:56 switchMailboxViewMode / renderCompactAccountList
12 布局系统回归(服务端同步布局/可拖拽列宽/密度模式) 基线 layout-manager.js(1407) + main.js:57/150/206/621
13 审计 trace_id 列缺失 基线 main.js:3825;后端 audit.py:92 返回但新页无列
14 审计详情 JSON 格式化与递归翻译丢失 基线 main.js:3756-3794;新页 audit/index.tsx:48v||'--'
15 审计动作色标 badge 丢失 基线 main.js:3812,3819;新页纯文本
16 审计 created_at 日期格式化丢失 基线 main.js:3821,3840;新页 audit/index.tsx:22 原样输出
17 groups 集成账号列表视图丢失 基线 groups.js(1017) 含 loadAccountsByGroup/sortAccounts/applyFiltersAndSort/handleTagFilterChange/searchAccounts;新 groups/index.tsx(266) 仅分组 CRUD
18 pool-admin 批量操作丢失 基线 pool_admin.js:202 batchPoolAdminAction:174 togglePoolAdminAll;新页仅单行 action

📊 迁移完整度(已核验领域)

领域 基线行数 新行数 完整度
Accounts 905 231 ~25%
Mailbox 1,627 476 ~30%
Groups 1,017 266 ~25%
Audit 121 字段契约错(页基本失效)
横切(轮询/i18n/布局) 8,841+ ~几百 ~15%
Settings 515 较完整(轮询配置是死配置)
Pool-admin 394 248 单行 action 完整,批量缺失
Temp-emails/Plugins/Token-tool/Refresh-log/Overview 待完整核验

✅ 建议合并路径

  1. 本 PR 内修 P0(4 项) → 重新冒烟时增加「审计列有数据」「能加号」「能复制验证码」「轮询配置生效或移除」用例
  2. P1 可作为本 PR 的后续 commit 或紧邻 PR
  3. P2 拆独立 PR 跟进

审查方法说明:12 领域对抗式 workflow(54 子代理)+ 直接源码 1:1 比对。workflow 因 schema 设计与 pipeline 聚合问题仅 audit 领域完成端到端对抗验证,其余领域结论来自直接阅读双方源码,每条附 file:line。如对某条结论有异议,欢迎指出,我会重新核验。

ZeroPointSix commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

本轮已处理 Slack / 审查中点出的 P0 implementation defects,并追加修复了 GitHub Code Quality 的 Black 格式失败。

修复内容:

  • 插件配置页:对齐后端 data.config_schema.fields / data.config 返回结构,保留旧结构 fallback。
  • 设置 cron 校验:请求体改为后端契约要求的 cron_expression
  • 审计日志 / 刷新日志:前端字段对齐 detailsuser_iptrace_idaccount_emailerror_message,并保留旧字段 fallback。
  • 概览 Activity Tab:对齐 kpinotification_statsop_type_disttimeline 契约,补齐通知推送、操作分布和系统活动展示。
  • 分组删除文案:改为说明账号会迁移到默认分组,系统分组不可删。
  • CI 格式:按 Black 要求格式化 tests/test_accounts_groups_api_contract.py

提交:

  • 07aca2b fix(frontend): align SPA API contracts
  • 1ab0b37 style(tests): satisfy black formatting

验证结果:

  • ant-design-pro npm ci:通过。
  • ant-design-pro npm run build:通过,生产构建成功。
  • black --check --diff outlook_web tests web_outlook_app.py outlook_mail_reader.py start.py:通过,251 files unchanged。
  • 后端契约套件:通过,Ran 41 tests ... OK(最终提交后复跑)。
  • GitHub CI:Code Quality run #154 已通过;Python Tests run #158 已通过。
  • SonarCloud Scan run #216 首次失败在 SonarQube Scan 阶段,日志为 SonarCloud 侧读取 PR key 109 失败(coverage 测试步骤已通过,不是代码测试失败)。已触发 failed jobs rerun;更新本评论时重跑仍在 Run tests with coverage 阶段。

已知未在本轮扩大的范围:

  • ant-design-pro npm run lint 仍会被既有 TypeScript 债务挡住,包括 cloudflare-worker/src/routes/* 缺少 ../data/*、多个既有 ProCard bordered 类型错误,以及 src/services/outlook/auth.tscsrf_disabled/csrf_token 的 AxiosResponse 类型问题。
  • ant-design-pro npm test 当前为 57/60,通过 9/10 个测试文件;3 个失败集中在既有 src/requestErrorConfig.test.ts 期望与实现不一致。
  • Cursor review 里更宽的产品能力缺口没有在这个 P0 契约修复提交中展开,避免把本轮修复范围扩大成重做功能。

Align Ant Design Pro admin with Flask contracts and old UI capabilities:
account batch/export, pool claimed rules, multi-key settings, mailbox
3-column workbench with resizable layout and compact poll controls.
@ZeroPointSix

Copy link
Copy Markdown
Owner Author

第二轮对抗式审查报告(含第一轮结论复核)

重大背景:第一轮审查(comment 4936120093)发出后,作者于 22:33 推送提交 d2711ce "feat(frontend): close PR #109 SPA parity gaps for P0-P2"(+3913/-357 行),直接针对第一轮清单做了修复。本轮逐条复核 d2711ce 后的代码状态,确认哪些已修、哪些仍存。

总体结论(第二轮)

合并阻塞已全部解除d2711ce 实质性地补回了第一轮 P0/P1/P2 的几乎所有项:审计字段契约、验证码提取、账号增改/批量/导出、轮询引擎、邮箱紧凑视图/全屏信任/CID/筛选、i18n 标题、审计 trace_id/格式化/色标/日期。建议改为「修完下列少量残留后可合」

本轮也纠正了第一轮两处误判(已在下方标注)。


✅ 第一轮 P0 复核 — 全部已修

# 第一轮结论 d2711ce 后状态 证据
P0-1 审计 3 列空白(detail/ip/operator ✅ 已修 audit/index.tsx:108 dataIndex:'details' + :112 row.details ?? row.detail 兼容;:127 dataIndex:'user_ip' + :130 row.user_ip || row.ipoperator 列已删除
P0-2 邮箱验证码提取缺失 ✅ 已修 mailbox/index.tsx:855-860 「提取并复制验证码」按钮 + onExtractVerification:861-873 「再次复制」lastVerification
P0-3 账号无增/改 ✅ 已修 accounts/index.tsx(231→888 行):ModalForm 新建/编辑、:262 编辑、:117 「智能识别(混合导入)」、batchDeleteAccounts/batchUpdateAccountGroup/batchUpdateAccountStatus/exportSelectedGroups/refreshSelectedAccounts/toggleAccountTelegram 全部接通
P0-4 轮询死配置 ✅ 已修 新增 services/outlook/pollEngine.ts(+280)::98-104enable_auto_polling/polling_interval/polling_count;mailbox :57-67,478-479,550startPoll/applyPollSettings。设置页配置现已被消费

✅ 第一轮 P1 复核 — 大部分已修

# 第一轮结论 d2711ce 后状态 证据
P1-5 邮箱 iframe 全锁死无信任切换 ✅ 已修 mailbox/index.tsx:530-538 buildEmailSrcDoc({...,trusted}):851-852 「信任原始 HTML」Switch + onToggleTrust
P1-6 i18n 回归 🟡 部分修 标题已接 useIntl(audit/overview/temp-emails/plugins/token-tool/refresh-log/groups/accounts 均已接,新增 locales/en-US/pages.ts+zh-CN/pages.ts);但列标题与栏内文案仍硬编码中文(如 audit/index.tsx:78 '时间':85 '动作'accounts/index.tsx:160 '邮箱')。英文环境下列名仍不可用
P1-7 CID 内联图片重写丢失 ✅ 已修 mailbox/index.tsx:535 inlineResources: detail.inline_resources + 新增 utils/emailHtml.ts(+110) buildEmailSrcDoc 处理内联资源
P1-8 账号其余 CRUD/批量/导出/Telegram ✅ 已修 见 P0-3 证据,批量/导出/Telegram/刷新/状态切换全通
P1-9 邮箱 URL 状态不完整 ✅ 已修 mailbox/index.tsx:126 history.replace(qs ? \/mailbox?${qs}` : '/mailbox')` —— 已改为带完整 qs 的 URL 同步
P1-10 邮箱排序/筛选缺失 ✅ 已修 mailbox/index.tsx:721-731 全部/未读/已读筛选;:732-741 箱内搜索

✅ 第一轮 P2 复核

# 第一轮结论 d2711ce 后状态 证据
P2-11 邮箱紧凑视图丢失 ✅ 已修 mailbox/index.tsx:556-685 groupsPane+accountsPane+viewMode 三栏 workbench;新增 components/MailboxLayout/ResizableWorkbench.tsx(+309)、utils/mailboxLayout.ts(+196) 可拖拽布局
P2-12 布局系统回归 ✅ 已修 同上 ResizableWorkbench + mailboxLayout 提供可拖拽列宽与布局持久化
P2-13 审计 trace_id 列 ✅ 已修 audit/index.tsx:133-146 dataIndex:'trace_id' + copyable
P2-14 审计详情 JSON 格式化 ✅ 已修 audit/index.tsx:53-69 formatDetails(JSON.parse + pretty + expandable);注:递归翻译 translateAuditDetailValue 仍未迁移(i18n 通病,列在残留)
P2-15 审计动作色标 badge ✅ 已修 audit/index.tsx:13-44 actionColor + :90 <Tag color={...}>
P2-16 审计日期格式化 ✅ 已修 audit/index.tsx:46-51 formatTime + :82
P2-17 groups 集成账号列表视图 ❌ 仍存 groups/index.tsx 仅 +9 行,仍为分组 CRUD;基线 groups.js(1017) 的 loadAccountsByGroup/sortAccounts/handleTagFilterChange/searchAccounts 主从视图未迁移(账号按分组查看已弱化迁移到 accounts 页的分组筛选下拉)
P2-18 pool-admin 批量操作 ⚪ 第一轮误判 第一轮判断有误:pool-admin 一直有 rowSelection+batchPoolAction+runBatch(6 个批量动作)。撤回此项

⚠️ 第一轮误判纠正(本轮自查发现)

  1. P2-18 pool-admin 批量操作:第一轮称「批量操作丢失」——错误。pool-admin 一直具备 rowSelection/batchPoolAction/runBatchpool-admin/index.tsx:16,86,108,211)。撤回。
  2. token-tool 明文显示 Token:第一轮曾拟列为安全问题——非回归。基线 token_tool.html:168 同样用 <textarea readonly> 明文显示。属既有设计,非本 PR 引入。
  3. groups「无新建」:第一轮曾存疑——错误。groups 一直有「新建分组」(groups/index.tsx:151-157+ModalForm:173)。撤回。

说明:第一轮 mailbox 部分结论基于提交 48eca53(mailbox 当时 476 行);d2711ce 将其扩展到 1346 行并补全功能。第一轮结论对当时代码状态成立,但对当前代码状态已过时,以本表为准。


🟡 残留问题(建议合并前或紧邻合并后处理)

R1. groups 集成主从视图仍缺(P2,唯一功能性残留)

  • 现状:groups/index.tsx 仅分组 CRUD,无「点分组→看组内账号→在组内排序/标签筛选/搜索」
  • 基线:groups.js:168 loadAccountsByGroup:467 sortAccounts:493 applyFiltersAndSort:498 handleTagFilterChange:515 searchAccounts
  • 影响:中等。账号按分组深度管理能力减弱(accounts 页有分组筛选但无标签/排序深度)
  • 建议:可作为独立 PR 跟进;或评估是否接受「分组仅 CRUD + accounts 页分组筛选」的新交互范式

R2. i18n 列标题/栏内文案仍硬编码(P2)

  • 现状:页面标题已接 useIntl,但列标题('时间'/'动作'/'邮箱'/'名称' 等)与栏内文案('暂无记录'/'确认删除该账号?')仍硬编码中文
  • 影响:英文/其他语言环境下列名与提示不可用
  • 建议:补 locales/*/pages.ts 的列标题消息 id 并替换硬编码

R3. overview「最近邮箱池操作」动态列脆弱(P2,新发现)

  • overview/index.tsx:661 Object.keys(recent[0] || { action: 1, created_at: 1 }) —— 数据为空时回退列显示字面量 1;列顺序/标签依赖数据
  • 建议:改为固定列定义

R4. 审计详情递归翻译未迁移(P2)

  • audit/index.tsx:53-69 formatDetails 做了 JSON pretty,但未迁移基线 main.js:3756-3769 translateAuditDetailValue 的递归翻译
  • 影响:与 R2 同属 i18n 范畴,低优先级

📊 复核统计

维度 第一轮 第二轮(d2711ce 后)
P0(合并阻塞) 4 0(全部已修)
P1 6 1 部分(i18n 列标题)
P2 8 3 残留(groups 视图/i18n/overview 动态列)+ 1 误判撤回
已确认安全/鉴权 CSRF(request.ts:39-44+重试)、鉴权(app.tsx:114-116) 均正常

✅ 第二轮建议

  1. 可合并:P0 全清,P1 实质已修。冒烟用例应补「审计列有数据/能加号/能复制验证码/轮询配置生效/邮箱三栏可拖拽」。
  2. 合并后跟进:R1 groups 主从视图(评估是否接受新范式)、R2 i18n 列标题、R3 overview 动态列、R4 审计详情递归翻译。
  3. 撤回第一轮误判:P2-18(pool-admin 批量)、token-tool 明文、groups 无新建。

本轮方法:逐条对照 d2711ce 后源码复核第一轮 18 项结论,并对第一轮做对抗式自查(纠错 3 项)。如对某条仍有异议,欢迎指出。

@ZeroPointSix

Copy link
Copy Markdown
Owner Author

UAT v2 部署结果(第二版)

机器do-64-227-openhands(并行 UAT,未动线上)
提交d2711cefeat(frontend): close PR #109 SPA parity gaps for P0-P2
(含此前 07aca2b SPA 契约对齐、b94fbfa Link import 修复)

访问

本轮动作

  1. git fetch origin pull/109/headpr-109-v2-uat @ d2711ce
  2. 后端 Docker 保持 healthy(v2 diff 主要为前端/契约测试,无后端业务路径强制 rebuild)
  3. ant-design-pro npm run build 成功(EXIT:0)
  4. Caddy 继续反代 /api /login /logout /img /healthz + SPA dist

冒烟

检查 结果
/healthz 200 ok / 2.7.0
CSRF + login + current-user + overview/summary 200
SPA 路由 shell 200
浏览器登录 Overview KPI 正常,footer d2711ce,无 console error
Mailbox 页 标准三栏 / 简洁切换、可调宽、Compact Poll、分组/账号/邮件面板渲染正常(空数据环境)

请直接打开 HTTPS 测第二版效果。

@cursor

cursor Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

第二版体验走查(有数据后):AI 味 / 不像正常产品

环境:UAT outlook-pr109.64-227-13-213.sslip.io @ d2711ce,已导入 16 个 Outlook 账号
方法:登录后逐页浏览器走查 + 对照源码(只审查,不改代码)

总印象

功能骨架比第一版完整很多,但产品感仍偏「Ant Design Pro 脚手架 + API 联调页」,不像已上线的运维后台。最刺眼的是:侧栏英文、副标题塞 API 路径、状态枚举原文、错误直接甩 JSON、页脚还写着 Ant Design Pro / Umi / Utoo。


P0 — 一眼就不像正常项目

  1. 全站副标题暴露 API / 联调备注
    实测:

    • Accounts:/api/accounts · import / edit / batch / export
    • Groups:对接 /api/groups
    • Mailbox:3-column workbench / compact / resizable layout
    • Pool:/api/pool-admin/* · claimed allows force_release only
    • Settings / Audit / Plugins / Token / Temp / Refresh:同类
      → 用户看到的是开发备注,不是产品说明。应改成一句业务文案,或直接去掉。
  2. 侧栏 / 页标题默认英文,正文中文
    菜单:Overview / Mailbox / Accounts / Temp Emails / Mail Pool / Token Tool
    页面里又是「刷新 / 添加账号 / 默认分组」。
    根因:locale 跟随浏览器(en-US),而产品默认应是中文运维后台。
    → 默认 zh-CN,语言切换可保留但不要默认英文化。

  3. 登录页模板残留

    • placeholder 仍是 Password: ant.designlocales/*/pages.ts 未改)
    • 按钮 Login(英文)
    • logo /img/ico.png 破图(全站侧栏也破)
    • 页脚 Ant Design Pro © 2026 + Umi / Utoo / GitHub
      → 这是最强的「还在用脚手架演示站」信号。
  4. Mailbox 错误体验极差
    Token 过期时整页大红 Alert + 原始 JSON(graph/imap_new/imap_old 全量堆栈)。
    另有英文控件:Compact Poll应用到引擎、Tag graph
    → 用户侧应是「授权已过期,请重新获取 Token」+「去 Token 工具」;技术详情折叠。

  5. 状态 / 枚举原文未本地化

    • 账号状态 Tag:active
    • 最近刷新:failed
    • 邮箱池状态:available
    • 列名 Provider
      → 应映射「正常 / 失败 / 可用」等中文。

P1 — 用起来别扭、像 AI 拼装

实测 建议
审计 Trace ID 显示 [object Object] ProTable render(v) 拿到的是 ReactNode;改用 (_, row) => row.trace_id
审计搜索占位 如 create/delete如 account/email 改成正常中文占位,别像字段说明书
分组颜色 表格直接显示 #666666 色块 + 颜色选择器
Overview 文案 「今日快捷数字」;KPI 显示活跃 16 但刷新成功率 0%/失败 16,信息互相打架 改「今日概览」;失败态要在总览更醒目
Accounts 工具栏 Reset / Query 英文,旁边中文「刷新/导出」 统一中文「重置/查询」
SettingDrawer 齿轮 右侧浮着 Pro 主题设置按钮 生产关掉
Token 工具 prompt=consent、Client ID/Scope 原样 中文标签 + 帮助说明
插件按钮 「应用变更」「读取 schema」 改「重新加载插件」等用户语言
信息架构 Token 工具与日常邮箱操作同级一级菜单 收到设置/账号授权下

P2 — 品牌与脚手架清理

  • manifest.json 仍是 Ant Design Pro
  • Footer 版权 / 默认 GitHub 回退到 ant-design/ant-design-pro
  • 登录背景仍是蚂蚁 CDN 图(源码)
  • 右上角 VersionDropdown / DocLink→/welcome 等 Pro 演示入口(若仍挂着)
  • 业务页大量 ProTable density/setting 默认开关,运维表不需要那么「组件秀」

有数据后的真实路径感受(简评)

  • 能用:账号列表能看到 16 个号,可编辑/删除/跳邮件;概览 KPI 有数;池列表有数。
  • 不好用:一进 Mailbox 就被 JSON 错误墙挡住;刷新全失败却在总览仍显示「活跃 16」;副标题/菜单/枚举持续提醒「这是联调站」。
  • 结论:第二版功能补齐方向对,但要先做一轮 去脚手架 / 去联调文案 / 中文化默认 / 错误可读化,否则体验上仍像 AI 生成的 Pro demo,而不是 OutlookEmailPlus 产品。

建议优先改(不改代码,仅排序)

  1. 删掉所有 对接 /api/... 副标题
  2. 默认中文 + 修 login placeholder / logo / footer
  3. Mailbox 错误可读化(禁止默认展开 JSON)
  4. 状态枚举中文化
  5. 修审计 Trace ID [object Object]

审查人:Cursor Cloud Agent · 对照提交 d2711ce

Replace API-style PageContainer subTitles with product copy, localize
status enums, improve mailbox errors, fix audit trace_id rendering,
default locale to zh-CN, and align brand/footer/logo for Outlook 邮件管理.

Co-authored-by: ZeroPointSix <ZeroPointSix@users.noreply.github.com>
@cursor

cursor Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

UX 打磨已合入本 PR 分支(待 UAT 重建)

已将体验修复推送到本分支 head:

  • 提交:17c5417fix(frontend): polish SPA UX to remove scaffold/AI feel
  • 同步分支:cursor/spa-ux-polish-d7dc

本轮改了什么(对应上一轮体验走查)

  1. 去掉 全站 对接 /api/... / 联调式 PageContainer 副标题 → 正常业务文案
  2. 默认 zh-CN;登录 placeholder「请输入登录密码」、按钮「登录」;清掉 ant.design
  3. 品牌:Footer / manifest / title → Outlook 邮件管理;去掉 Umi/Utoo;GitHub 指向本仓库
  4. 状态中文化:active/failed/available…;Provider → 来源
  5. Mailbox 错误:可读中文原因 + 重试;JSON 进可折叠「技术详情」
  6. 审计 Trace ID:修复 [object Object](改用 row.trace_id
  7. Logo:SPA public/img/ico.png;生产隐藏 SettingDrawer

请在 UAT 机 do-64-227-openhandsfeat/ant-design-pro-frontend-migration / 17c5417 重新 build SPA 并部署后验收。

@ZeroPointSix

Copy link
Copy Markdown
Owner Author

UAT v3 覆盖部署(UX 打磨)

机器do-64-227-openhands
提交17c5417fix(frontend): polish SPA UX to remove scaffold/AI feel

动作

  • git fetch origin pull/109/headpr-109-v3-uat @ 17c5417
  • ant-design-pro npm run build EXIT:0(覆盖原 dist)
  • 后端容器保持 healthy,Caddy 反代不变

验证

@ZeroPointSix ZeroPointSix left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CodeXWeb 深度审查 @ 17c5417

结论:这版 UX 打磨有效,插件、设置、账号导入等上一轮 P0 大多已修;但我不建议直接合并到默认流量。至少需要先处理下面两个功能契约问题。

Findings

  1. P1 阻塞:批量“刷新 Token”仍把 SSE 流当普通 JSON 请求处理。
    ant-design-pro/src/services/outlook/accounts.ts:235-244 / ant-design-pro/src/pages/accounts/index.tsx:506-518 直接 await refreshSelectedAccounts() 并读取 res.success/message;但后端 outlook_web/controllers/accounts.py:2757-2805 明确返回 text/event-stream。现有测试 tests/test_refresh_selected_issue45.py:165-180 也按 data: 事件解析并校验 start/complete
    结果:选中多个账号刷新时前端不会展示逐账号进度、跳过、失败信息,长任务会像卡住,最终也可能把流式结果误当普通响应。建议前端改成 fetch stream 解析 SSE,或新增非流式提交端点,并把 start/progress/complete/error 映射到 UI。

  2. P1:分组选中导出按 fetch Response 写法处理,但当前请求栈是 axios-style,成功下载和文件名解析都有风险。
    ant-design-pro/src/services/outlook/accounts.ts:265-291getResponse: true + responseType: 'blob' 后把 res.response 强转成 fetch Response,用 response.ok 判断成功、用 response.headers.get('Content-Disposition') 取文件名。项目请求层和配置是 axios 形态(ant-design-pro/config/config.ts:160ant-design-pro/src/app.tsx:170ant-design-pro/src/requestErrorConfig.ts:80-81ant-design-pro/src/services/outlook/request.ts:56-57);axios response 没有 ok,headers 也不是 Headers.get()。后端 outlook_web/controllers/accounts.py:2257-2261 返回的文件名 header 因此读不到;如果运行时确实返回 axios response,200 成功也会被 !response.ok 误判成失败。
    建议兼容 axios/fetch 两种 response:用 status >= 200 && status < 300ok 判断;header 同时支持 headers.get()headers['content-disposition'];并补一个 blob 下载单测覆盖 200 与错误 blob。

  3. P2:仍有少量“技术字段裸露”的体验残留。
    比如 ant-design-pro/src/pages/temp-emails/index.tsx:307-310Providerant-design-pro/src/pages/settings/index.tsx:819-827API Base/API Keyant-design-pro/src/pages/accounts/index.tsx:730-745Fallback IMAP Host/IMAP Port。这不阻塞功能,但和本轮“去脚手架/AI 味”的目标还差一点,可以统一成面向运维用户的中文文案与说明。

已核对通过

  • 插件配置 schema 路径已对齐:plugins.ts:71-83routes/plugins.py:43-50
  • Cron 校验字段已对齐:settings.ts:51-59cron_expression,后端 settings.py:1182 读取同名字段。
  • 账号导入/编辑主链路已补齐;IMAP 编辑的 password 会在仓储层转写到 imap_password,不是问题。
  • 当前 active routes 只挂业务页面;旧 Ant Pro 示例页残留主要是仓库/包体清理,不是当前可见路由问题。

验证

  • GitHub Actions:Code Quality 通过,Python Tests 通过。
  • SonarCloud Scan 失败点在 SonarQube Scan 步骤;同 job 的 Run tests with coverage 已通过。日志显示它在 PR key 110 上取 Sonar PR 信息失败,属于扫描/ALM 配置问题,不能当作 Python 测试失败。
  • MCP 远端全量验证尝试:本沙箱缺 Python 依赖(Flask/requests)且 npm ci 被 OOM kill(exit 137),所以 sandbox 内 backend/frontend 全量测试没有有效跑完;以 CI 结果为准。

Address PR #109 deep-review P1/P2: parse refresh/selected as SSE with
progress UI and timeouts, make export-selected axios/fetch compatible,
and localize remaining technical field labels.

Co-authored-by: ZeroPointSix <ZeroPointSix@users.noreply.github.com>
@cursor

cursor Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

审查意见修复 + 对抗式复查 @ 2b70f1c

已按深度审查(review 4676200392)修复,并做对抗式复查。

修复对照

审查项 状态 说明
P1 批量刷新 Token 把 SSE 当 JSON ✅ 已修 accounts.ts 改用 fetch + ReadableStream 解析 data:;处理 start/progress/delay/complete/error;UI 进度 toast;2min 总超时 + 30s 心跳(对齐旧 main.js
P1 导出 blob 按 fetch Response 写、实际 axios ✅ 已修 isHttpOk / getResponseHeader / parseContentDispositionFilename 兼容 axios+fetch;错误 blob 解析 JSON
P2 Provider / API Base / IMAP Host 等裸露 ✅ 已修 临时邮箱「服务商」、设置「接口地址/密钥/Cloudflare Worker…」、账号「IMAP 主机/端口/备用主机」

单测

ant-design-pro/src/services/outlook/accounts.test.ts:SSE 分片解析 + 导出 header/ok 兼容 → 5/5 通过

对抗式复查结论

  • 无 P0 阻塞残留;原两条 P1 已实质修复。
  • 非阻塞残留(不挡本轮):settings 外部 API 区仍有少量英文技术词(如表格列「API Key」);invalid_token_failed_list 未单独 surfaced。
  • 建议:本轮审查阻塞项可关闭;合并默认流量前仍建议在 UAT 点测「刷新 Token」进度与「分组导出」文件名。

提交:2b70f1c(已在 feat/ant-design-pro-frontend-migration
同步 PR:#111

@cursor

cursor Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

新加坡 UAT 部署完成 @ 2b70f1cdo-sgp-001

由 Hermes 在新加坡机 Docker 部署;未动线上 do-nyc-001

访问

冒烟(Hermes + 外部复核)

检查 结果
/healthz 2.7.0
登录 / 概览 / 侧栏中文
批量刷新 Token SSE 进度 start → progress → complete(不再卡住)
分组导出带文件名 txt Content-Disposition: filename*=UTF-8''accounts_export_selected_…txt

本轮审查修复(SSE / 导出兼容)已在新加坡 UAT 验证通过。

Keep login, accounts, mailbox, groups and SSE/export flows; drop
scaffold demos and non-core pages/services/deps for a smaller PR.
…isplay-20260810

fix(zer-582): 在纯白主题下恢复服务展示优化
@railway-app
railway-app Bot temporarily deployed to outlook-email-plus / production August 11, 2026 01:11 Inactive
@railway-app
railway-app Bot temporarily deployed to outlook-email-plus / production August 13, 2026 03:33 Inactive
ZeroPointSix and others added 13 commits August 13, 2026 11:36
- app.tsx: SettingDrawer 增加 isDev 条件,生产构建不再暴露开发态设置抽屉
- 新增 ThemeToggle 组件:右上角浅色/深色切换,仅暴露产品允许的选项
- 主题偏好持久化到 localStorage,启动时恢复
- 补充 ThemeToggle 持久化单测
- 新增 services/outlook/tags.ts:接入 /api/tags 与 /api/accounts/tags
- 账号列表新增标签列(彩色 chip 展示)
- 搜索表单支持按标签多选筛选(后端 tag_ids 逗号分隔参数)
- 行内「打标」下拉:已有标签显示 ✓ 可移除,未有显示 + 可添加
- 批量工具栏新增添加/移除标签
- 工具栏新增「标签管理」入口:新建(名称+颜色)、删除标签
- 补充 tags service 单测
生产环境 SettingDrawer 不再渲染后,原菜单项会变成死按钮。
现在开发环境保留打开抽屉;生产环境直接切换浅色/深色并持久化,
与右上角 ThemeToggle 行为一致。
fix(zer-658): 生产环境隐藏开发态主题抽屉并新增正式主题入口
@railway-app
railway-app Bot temporarily deployed to outlook-email-plus / production August 14, 2026 07:20 Inactive
feat(zer-653): 新前端账号标签能力——展示/筛选/打标/标签管理
@railway-app
railway-app Bot temporarily deployed to outlook-email-plus / production August 14, 2026 07:21 Inactive
森果云 and others added 2 commits August 14, 2026 15:23
- 行内新增「验证码」:调用 /api/emails/{email}/extract-verification,
  结果弹窗展示验证码/验证链接并支持一键复制,可跳转邮箱页
- 行内新增「移组」下拉:快速移动单个账号分组
- 操作列宽度调整,提取中状态防重复点击
…actions

fix(zer-660): 账号行内补齐旧站简洁模式高频操作
@railway-app
railway-app Bot temporarily deployed to outlook-email-plus / production August 14, 2026 07:26 Inactive
@railway-app
railway-app Bot temporarily deployed to outlook-email-plus / production August 14, 2026 08:42 Inactive
fix(zer-657): 补齐新前端临时邮箱设置入口与配置表单
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants