boardx / boardx/workspacex

lint-nav-reachability: 补一条「同束内页面必须至少被一个真实链接引用」检查(F318 跟进)

Open
#319 0 comments 0 reactions 0 assignees View on GitHub
backlog out-of-scope owner:coord-architecture
Dominant language
TypeScript
Stars
0
Forks
0
Avg merge
1h 7m
Merged PRs (30d)
969

Description

## 背景

F318(#318)修的是:`apps/web/app/tpl/designer/page.tsx` 是蓝本设计器的真实挂载点,但全仓零 ``/`router.push` 指向它——左侧导航和「编辑设计」CTA 都还接在 `/tpl?screen=designer` 这个原型态上。这个漂移之所以没被拦住,是因为现有 `.harness/scripts/lint-nav-reachability.mjs` 只检查**导航树 → 束路由**这一层(`navigation.ts` 里的 href 能不能解析到束的现行 `page.tsx`),完全不看**页面内部**渲染的是哪个子组件、也不看**某个 `page.tsx` 文件本身是否被任何组件内部的 CTA 引用过**。

`/tpl/designer/page.tsx` 是一个真实存在、解析得到、甚至被写进 `nav-reachability.config.json`/`ui-material-map.json` 的合法路由(如果它在配置里的话——需要核实),所以现有五条判定全部通过,问题却依然存在:它是「页面内部渲染分叉出的孤儿页」,不是「导航树缺项」。

## 建议方向(原 #318 里提出,评估后判断是更大的改动,故拆出来单独跟踪)

给 `lint-nav-reachability.mjs`(或新脚本)加一条检查:
- 枚举 `apps/web/app/**/page.tsx`(排除 `(group)`/动态段的特殊情况);
- 对每个 page 路由,在 `apps/web/components/**` + `apps/web/app/**` 里 grep 是否有任何字符串字面量/模板字面量引用了这个路径(`href="..."`、`router.push("...")`、`redirect("...")` 等);
- 排除已知合法的「无内部引用」场景:根路由、通过 `navigation.ts` 直接可达的路由(不需要页面内部再引用一次)、显式标注为 deprecated-redirect 的页面(如 `/studio/interview`)。

## 为什么没在 #318 里顺手做

评估后发现这条检查比 F318 本身的路由修复复杂得多,风险点包括:
- 动态段 `[id]`/catch-all 路由的匹配需要正则而非字面量比较,容易漏报或误报;
- 有些页面故意只能通过 `redirect()` 到达(如 `/studio/interview`),不该算孤儿;
- 有些页面路由字符串是运行时拼出来的(模板字符串 + 变量),静态 grep 抓不到,会有噪音误报;
- 需要一份「排除清单」机制,否则会拦住大量本来就设计成「仅导航可达、无需内部再链接」的叶子页面。

在没有先想清楚排除规则和匹配算法之前贸然加门控,容易做出一个「一堆误报靠人肉豁免」的新版本——这正是仓库里反复出现「写完门控立刻造反证」的教训(见 workspacex-gate-counterproof-discipline 记忆)。所以按 #318 的原始建议,单独开一条 issue 来做,不在这次路由修复 PR 里塞。

## 验收方向(草案,非最终)

- 新增检查能在测试夹具里复现 F318 这个具体场景:一个真实存在、可解析的 `page.tsx`,但仓内没有任何组件对它的路径做字符串引用 → 报红。
- 至少覆盖一个"故意允许无内部引用"的豁免用例(如 deprecated-redirect 页面)不报红。
- 现有 `lint-nav-reachability.test.ts` 全部保持通过。

Contributor guide

No contributing guide indexed for this repository

Research direction

Read .harness/scripts/lint-nav-reachability.mjs and lint-nav-reachability.test.ts first, then inspect nav-reachability.config.json and ui-material-map.json. Use a test fixture for the F318 orphan-page case and a deprecated-redirect exemption. Done means the orphan is reported, the exemption is accepted, and the existing test suite remains passing.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, typescript
Domain
testing, tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.