From 9568168bfcc56a127cb775748792c0caec6fa0cd Mon Sep 17 00:00:00 2001 From: shunli Date: Thu, 16 Jul 2026 16:46:56 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=B0=E5=BD=95=E6=97=A7=20Portal=20?= =?UTF-8?q?=E5=85=BC=E5=AE=B9=E6=B8=85=E7=90=86=E8=AF=81=E6=8D=AE=EF=BC=88?= =?UTF-8?q?07-16-legacy-portal-navigation-compat-cleanup=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../check.jsonl | 1 + .../design.md | 56 +++++++ .../implement.jsonl | 1 + .../prd.md | 147 ++++++++++++++++++ .../research/portal-compat-audit.md | 59 +++++++ .../task.json | 32 ++++ 6 files changed, 296 insertions(+) create mode 100644 .trellis/tasks/07-16-legacy-portal-navigation-compat-cleanup/check.jsonl create mode 100644 .trellis/tasks/07-16-legacy-portal-navigation-compat-cleanup/design.md create mode 100644 .trellis/tasks/07-16-legacy-portal-navigation-compat-cleanup/implement.jsonl create mode 100644 .trellis/tasks/07-16-legacy-portal-navigation-compat-cleanup/prd.md create mode 100644 .trellis/tasks/07-16-legacy-portal-navigation-compat-cleanup/research/portal-compat-audit.md create mode 100644 .trellis/tasks/07-16-legacy-portal-navigation-compat-cleanup/task.json diff --git a/.trellis/tasks/07-16-legacy-portal-navigation-compat-cleanup/check.jsonl b/.trellis/tasks/07-16-legacy-portal-navigation-compat-cleanup/check.jsonl new file mode 100644 index 00000000..9dd3234a --- /dev/null +++ b/.trellis/tasks/07-16-legacy-portal-navigation-compat-cleanup/check.jsonl @@ -0,0 +1 @@ +{"_example": "Fill with {\"file\": \"\", \"reason\": \"\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."} diff --git a/.trellis/tasks/07-16-legacy-portal-navigation-compat-cleanup/design.md b/.trellis/tasks/07-16-legacy-portal-navigation-compat-cleanup/design.md new file mode 100644 index 00000000..6d128a4d --- /dev/null +++ b/.trellis/tasks/07-16-legacy-portal-navigation-compat-cleanup/design.md @@ -0,0 +1,56 @@ +# 旧 Portal 导航兼容清理设计 + +## Safety Boundary + +本任务只移除已经没有实际调用链的兼容描述和重复报告字段。`Portal` 作为负向英文检测词、`/portal` 路由和内部技术标识继续保留;历史审计文件保持只读。 + +## Classification Matrix + +| 类别 | 例子 | 处理 | +| --- | --- | --- | +| 当前用户导航合同 | `工作台` | 保留并作为唯一允许 label | +| 失效双文案兼容 | 部署规约中的 `工作台 | Portal` | 删除旧 fallback | +| 负向视觉检测 | `ENGLISH_PRIMARY_TERMS` 中的 `Portal` | 保留,用于发现英文旧词回归 | +| 重复报告字段 | `navPortalCopy` | 删除;`englishFound` 已覆盖同一信号 | +| 内部技术标识 | `/portal`、`assertPortalLoaded`、Portal API/组件 | 保留 | +| 历史证据 | 归档 summary、Issue CSV、旧截图 | 保留,不改写 | +| 现行手册术语 | 管理员/员工/部署手册中的 `Portal` | 由用户决定是否另行迁移 | + +## Implementation + +### 最小方案 + +1. 把部署规约的当前 label 合同收敛为精确 `工作台`。 +2. 移除规约中的旧 mock/fallback 描述和 `.or(...Portal)` 示例。 +3. 从只读视觉报告对象中移除 `navPortalCopy` 的采集与输出。 +4. 保持 `Portal` 在 `ENGLISH_PRIMARY_TERMS` 中,从而继续生成英文文案 finding。 + +### 扩展方案 + +若用户选择现行手册迁移,先由文档状态矩阵筛出 CURRENT 用户/运维事实源,再逐条区分用户文案、历史描述和技术路由,不能全局替换。 + +## Validation Matrix + +| 条件 | 预期 | +| --- | --- | +| 当前导航源和 mock label | 只有 `工作台` | +| 部署规约导航 fallback | 不再允许 `Portal` | +| 视觉英文词检测 | 仍包含 `Portal` | +| 新报告 schema | 无 `navPortalCopy`,保留 `englishFound` | +| 历史归档报告 | 不修改,仍可保留旧字段 | +| TypeScript / Playwright `--list` / build | 通过 | +| Trellis/task/diff 门禁 | 通过 | + +## Failure Handling + +- 发现现行消费者读取 `navPortalCopy`:停止删除该字段,先迁移消费者并更新合同。 +- 发现 fixture 仍输出 `Portal`:先判断是否仍为合法用户体验;不能靠继续放宽 smoke 掩盖文案回归。 +- Playwright spec 加载或类型检查失败:恢复相关改动并按最小范围修复,不扩展到内部符号重命名。 + +## Rollback + +从任务提交的父提交恢复部署规约段落和 `navPortalCopy` 两处代码即可;不涉及数据库、路由、配置或生产数据回滚。 + +## Verification Boundary + +本任务的默认验证为本地静态、TypeScript、Playwright spec 加载与 build。未获单独批准时不运行带凭据公网 smoke/视觉审计,不宣称已部署或线上可测。 diff --git a/.trellis/tasks/07-16-legacy-portal-navigation-compat-cleanup/implement.jsonl b/.trellis/tasks/07-16-legacy-portal-navigation-compat-cleanup/implement.jsonl new file mode 100644 index 00000000..9dd3234a --- /dev/null +++ b/.trellis/tasks/07-16-legacy-portal-navigation-compat-cleanup/implement.jsonl @@ -0,0 +1 @@ +{"_example": "Fill with {\"file\": \"\", \"reason\": \"\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."} diff --git a/.trellis/tasks/07-16-legacy-portal-navigation-compat-cleanup/prd.md b/.trellis/tasks/07-16-legacy-portal-navigation-compat-cleanup/prd.md new file mode 100644 index 00000000..8df83fe1 --- /dev/null +++ b/.trellis/tasks/07-16-legacy-portal-navigation-compat-cleanup/prd.md @@ -0,0 +1,147 @@ +# 清理旧 Portal 导航兼容 + +## Goal + +移除已经失效的 `Portal` 导航双文案兼容和重复报告字段,使公网 smoke、视觉审计与当前产品文案统一以 `工作台` 为准,同时保留 `/portal` 路由、内部技术标识、对用户可见英文 `Portal` 的负向检测以及历史审计材料。 + +## Scope + +- 最小推荐范围:更新部署规约中的 `工作台 | Portal` 双接受合同为仅接受 `工作台`。 +- 删除只读视觉报告中与 `englishFound` 重复、无现行消费者的 `navPortalCopy` 字段。 +- 保留 `ENGLISH_PRIMARY_TERMS` 中的 `Portal`,继续把用户可见英文旧词视为视觉 finding。 +- 现行用户/运维手册中的 `Portal` 术语不在本批迁移范围。 + +## What I Already Know + +- 当前前端导航、后端 workspace 默认导航和所有现行 mock fixture 都使用 `工作台`。 +- `client/tests/e2e/helpers/smokeAssertions.ts` 自 2026-05-29 起只接受精确中文 `工作台`,没有运行时代码仍执行双文案兼容。 +- `.trellis/spec/hyb-oa/deployment-trialrun.md` 仍声称旧 mock 可输出 `Portal`,并给出 `.or(...Portal)` 示例;该规约已与实际 helper 漂移。 +- 当前 mock/fixture 中未发现 `label: "Portal"` 或等价单引号写法。 +- `client/tests/e2e/oafront3-pc-readonly-visual.spec.ts` 把 `Portal` 纳入禁止英文主展示词,这是应保留的负向检测。 +- 同一视觉报告另行输出 `navPortalCopy: text.includes("Portal")`,但 `englishFound` 已包含相同信号;现行代码没有消费者。 +- 归档视觉报告包含旧 `navPortalCopy` 字段,属于历史证据,不改写。 +- `/portal` 路由、`assertPortalLoaded`、`PortalHomePage`、Portal API/数据库标识和测试标题是仍在使用的内部技术标识,不等同于用户可见旧导航兼容。 +- 多份当前手册和业务规约仍用 `Portal` 指代工作台;一次性迁移会显著扩大审阅范围。 + +## Confirmed Scope + +- 用户于 2026-07-16 选择方案 1,采用最小兼容清理,不把文档术语迁移和内部符号重命名混入同一批。 +- 移除重复报告字段不会影响历史报告读取,因为未发现现行聚合器或门禁消费该字段。 +- 本任务不改变路由、导航结构、页面视觉、角色权限或部署行为。 + +## Open Questions + +- 无。 + +## Requirements + +- 规约必须准确反映现行 smoke helper:导航仅接受 `工作台`。 +- 删除重复的 `navPortalCopy` 新报告字段,但保留 `Portal` 英文负向检测。 +- 保留 `/portal` 路由和所有仍有消费者的内部 Portal 技术标识。 +- 不改写历史 Issue、归档 task 或归档视觉报告。 +- 验证 TypeScript、Playwright spec 加载、前端构建和 Trellis 治理。 +- 验证产生的 `client/dist/`、Playwright report 和 test-results 在取证后清理。 + +## Acceptance Criteria + +- [x] 部署规约不再声明或示范 `工作台 | Portal` 导航双接受。 +- [x] `smokeAssertions.ts` 继续精确断言 `工作台`,不新增其他旧词 fallback。 +- [x] 新生成的只读视觉报告不再包含重复字段 `navPortalCopy`。 +- [x] `ENGLISH_PRIMARY_TERMS` 仍包含 `Portal`,用户可见旧英文文案仍产生 finding。 +- [x] 当前 mock/fixture 不含 `Portal` 导航 label。 +- [x] `/portal` 路由与内部 Portal 标识保持不变。 +- [x] TypeScript、Playwright spec `--list`、前端 build、task/governance/diff 门禁通过。 +- [x] 最终工作树不包含验证生成物,修改范围与用户选择一致。 + +## Feasible Approaches + +### 方案 1:最小兼容清理(推荐) + +- 更新部署规约为中文单一合同。 +- 删除重复 `navPortalCopy` 报告字段。 +- 保留负向英文检测、内部标识和所有现行/历史文档原状。 +- 优点:两处小改、风险最低,直接解决实际兼容漂移。 +- 缺点:部分现行手册仍使用 `Portal` 作为工作台术语。 + +### 方案 2:兼容清理 + 现行手册术语迁移 + +- 在方案 1 基础上,把 CURRENT 用户/运维文档中面向人的 `Portal` 改为 `工作台`。 +- 优点:用户和运维文案更一致。 +- 缺点:涉及多份事实源,需要逐条判断历史描述、路由名与当前体验,回归面明显扩大。 + +### 方案 3:连内部 Portal 标识一起重命名 + +- 同时重命名路由、组件、API、测试标题或数据库技术标识。 +- 不推荐:没有用户价值,会制造跨前后端、数据与历史兼容风险。 + +## Definition of Done + +- 用户选择的范围完成并记录,未顺带重命名内部技术标识。 +- 兼容删除有静态引用、历史、报告消费者和回滚证据。 +- 前端与治理门禁通过,生成物清理完成。 +- 形成中文本地提交计划并另行取得提交确认;不自动 push 或部署。 + +## Technical Approach + +1. 区分用户可见旧词、负向检测、内部标识、现行手册与历史证据。 +2. 以现行 helper 和导航源为事实,删除规约中的虚假双接受描述。 +3. 删除只读视觉报告中的重复字段,保留 `englishFound` 的 `Portal` 负向信号。 +4. 运行静态引用、TypeScript、Playwright 加载、build 和治理门禁。 + +详细引用矩阵、验证边界与回滚见 `design.md` 和 `research/portal-compat-audit.md`。 + +## Decision (ADR-lite) + +**Context**:运行时已经中文单一化,但部署规约仍保留旧 fallback,视觉报告又重复输出相同旧词信号;同时内部 `/portal` 技术标识和历史证据仍有合法用途。 + +**Decision**:用户已选择方案 1;只删失效兼容和重复报告字段,不做大范围术语或内部符号迁移。 + +**Consequences**:当前导航合同与代码重新一致,未来报告更精简;现行手册术语一致性留待独立文档治理批次。 + +## Test Plan + +```bash +cd client && npm run typecheck +cd client && npx playwright test tests/e2e/oafront3-pc-readonly-visual.spec.ts --list +cd client && npx playwright test tests/e2e/visual-shell.spec.ts --list +cd client && npm run build +python3 ./.trellis/scripts/task.py validate 07-16-legacy-portal-navigation-compat-cleanup +node scripts/qa/check-trellis-governance.mjs +git diff --check +``` + +- 不运行带凭据公网视觉审计或 live smoke;若需要真实公网复核,必须另行批准并提供前置条件。 +- 不执行部署、生产配置修改、数据库写入或企业微信写入。 + +## Verification Results + +- `smokeAssertions.ts` 仍有两处精确 `工作台` 导航断言;当前前后端及 fixture 搜索未发现 `Portal` 导航 label。 +- 活跃测试、规约、脚本和部署范围中 `navPortalCopy` 引用为 0;受保护归档报告仍保留旧字段。 +- `ENGLISH_PRIMARY_TERMS` 继续包含 `Portal`,`englishFound` 仍是用户可见英文旧词的单一 finding 信号。 +- `cd client && npm run typecheck` 退出码为 0。 +- 两个相关 Playwright spec 使用 `--list` 成功加载,共列出 2 个文件、6 个测试;未启动浏览器或访问公网。 +- `cd client && npm run build` 退出码为 0:Vite 转换 2381 个模块,PWA 生成 102 个预缓存条目;仅有既有 Browserslist 数据陈旧提示。 +- task validate、Trellis governance 和 `git diff --check` 严格模式通过;治理无 warning/error。 +- `client/dist`、`client/playwright-report` 和 `client/test-results` 已清理。 +- 独立只读复核无阻断:确认精确中文导航合同、`englishFound` 检测能力、内部标识与历史证据边界均保持完整,工作树未超出方案 1。 +- 未执行 live smoke、带凭据视觉审计、部署、push 或任何数据写入。 + +## Out of Scope + +- 未经选择的现行手册术语批量迁移。 +- `/portal` 路由、Portal API、数据库字段、组件名和内部 helper 名重命名。 +- 改写历史 Issue CSV、归档 task、归档视觉报告或旧截图。 +- 页面布局、视觉、交互、权限、导航分组或业务能力调整。 +- push、部署、公网检查或真实数据写入。 + +## Technical Notes + +- 当前中文导航源:`client/src/components/navigation/NavLinks.tsx`、`client/src/features/navigation/schema.ts`、`server/src/services/workspaceSettings.js`。 +- 当前 smoke helper:`client/tests/e2e/helpers/smokeAssertions.ts`。 +- 待清理规约:`.trellis/spec/hyb-oa/deployment-trialrun.md`。 +- 待精简报告:`client/tests/e2e/oafront3-pc-readonly-visual.spec.ts`。 +- 上一批候选:`.trellis/tasks/archive/2026-07/07-15-production-trust-closeout-cleanup/research/cleanup-candidate-inventory.md`。 + +## Research References + +- `research/portal-compat-audit.md`:导航源、fixture、规约、视觉报告、历史证据和内部标识分类结果。 diff --git a/.trellis/tasks/07-16-legacy-portal-navigation-compat-cleanup/research/portal-compat-audit.md b/.trellis/tasks/07-16-legacy-portal-navigation-compat-cleanup/research/portal-compat-audit.md new file mode 100644 index 00000000..34d1049d --- /dev/null +++ b/.trellis/tasks/07-16-legacy-portal-navigation-compat-cleanup/research/portal-compat-audit.md @@ -0,0 +1,59 @@ +# 旧 Portal 导航兼容审计 + +## Summary + +当前运行时已经不存在 `Portal` 导航双接受:前端、后端、fixture 和 smoke helper 均以 `工作台` 为唯一用户导航 label。剩余可清理项是部署规约的过时 fallback 描述,以及视觉报告中与 `englishFound` 重复的 `navPortalCopy` 字段。 + +## Current Navigation Sources + +- 前端默认导航:`NavLinks.tsx` 使用 `工作台`。 +- 前端路由元数据:navigation schema 使用 `工作台`。 +- 后端 workspace 导航:workspace settings 使用 `工作台`。 +- 当前 E2E fixture 搜索未发现 `label: "Portal"`。 +- `smokeAssertions.ts` 对工作台链接使用精确中文断言。 + +## History + +- Git blame 显示 smoke helper 在 2026-05-29 已从旧英文 label 迁移到 `工作台`。 +- 部署规约仍描述旧 fixture 和 `.or(...Portal)` fallback,已经落后于代码事实。 +- 归档只读视觉报告保留 `navPortalCopy: false`,属于当时的审计 schema,不应改写。 + +## Visual Audit Field + +- `ENGLISH_PRIMARY_TERMS` 包含 `Portal`,页面出现该用户可见英文词时会进入 `englishFound` 并产生 finding。 +- `readMetrics` 另行计算 `navPortalCopy: text.includes("Portal")`,报告对象再次输出该布尔值。 +- 当前仓库除该测试文件和受保护归档报告外,没有现行消费者读取 `navPortalCopy`。 +- 因此删除未来报告的 `navPortalCopy` 不会降低检测能力,也不会破坏现行门禁;`englishFound` 是保留的单一信号。 + +## Protected Internal Identifiers + +- `/portal` 是现行路由和 Enterprise WeChat return target。 +- Portal API、feature flag、数据库实体、组件和 helper 名仍有大量消费者。 +- 测试标题中的 Portal 多为内部场景名,不是导航 fallback。 +- Radix UI 的 `DialogPrimitive.Portal` / `DropdownMenuPrimitive.Portal` 是第三方渲染概念,与产品文案无关。 + +## Current Documentation + +- 多份 CURRENT 用户、管理员、业务和部署手册仍用 `Portal` 指代工作台。 +- 这些文档混合了当前操作说明、历史结论、路由术语和内部模块名;若迁移必须按状态矩阵逐份审核。 +- 不建议把文档迁移与两处兼容清理自动捆绑,也不能全局替换。 + +## Recommended Scope + +采用最小方案:更新部署规约,删除重复报告字段,保留英文负向检测、内部标识、现行手册和历史证据。后续若用户希望统一手册术语,另建文档治理批次。 + +## Validation + +- 精确搜索当前 mock label 和 `navPortalCopy` 消费者。 +- 前端 TypeScript 检查。 +- 两个相关 Playwright spec 使用 `--list` 加载。 +- 前端 production build。 +- Trellis governance、task validate 和 `git diff --check`。 + +## 2026-07-16 Execution Result + +- 用户选择最小方案;部署规约已收敛为精确中文导航合同。 +- 新视觉报告已移除重复 `navPortalCopy` 字段,`Portal` 英文负向检测保持不变。 +- 当前 fixture 的旧导航 label 和活跃重复字段消费者均为 0。 +- TypeScript、两个 Playwright spec 的 `--list`、production build 和 Trellis 治理通过。 +- 验证生成物已清理;未运行公网或带凭据检查。 diff --git a/.trellis/tasks/07-16-legacy-portal-navigation-compat-cleanup/task.json b/.trellis/tasks/07-16-legacy-portal-navigation-compat-cleanup/task.json new file mode 100644 index 00000000..0d734a9d --- /dev/null +++ b/.trellis/tasks/07-16-legacy-portal-navigation-compat-cleanup/task.json @@ -0,0 +1,32 @@ +{ + "id": "legacy-portal-navigation-compat-cleanup", + "name": "legacy-portal-navigation-compat-cleanup", + "title": "清理旧 Portal 导航兼容", + "description": "移除已经失效的 Portal 导航双文案兼容和重复视觉报告字段,同时保留中文负向检测、内部路由标识与历史证据。", + "status": "in_progress", + "dev_type": null, + "scope": "deployment navigation spec, focused Playwright visual report compatibility, and current Trellis evidence", + "package": null, + "priority": "P2", + "creator": "shunli", + "assignee": "shunli", + "createdAt": "2026-07-16", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": null, + "relatedFiles": [ + ".trellis/spec/hyb-oa/deployment-trialrun.md", + "client/tests/e2e/helpers/smokeAssertions.ts", + "client/tests/e2e/oafront3-pc-readonly-visual.spec.ts", + "client/src/components/navigation/NavLinks.tsx", + "server/src/services/workspaceSettings.js" + ], + "notes": "用户于 2026-07-16 选择方案 1;过时导航 fallback 和重复视觉报告字段已清理,本地门禁通过,现行手册与内部 Portal 标识保持不变。", + "meta": {} +}