Files
dsh_ai1net_server/交付物/DSH项目架构全景图_20260921.html
T

254 lines
83 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html lang="zh-CN"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>DSH 项目架构全景图 · 2026-09-21</title>
<style>
*{box-sizing:border-box;margin:0;padding:0}
:root{--bg:#0b1424;--card:#111e33;--card2:#0e1a2c;--bd:#1e3050;--tx:#e6edf7;--tx2:#93a4be;
--ac:#38d6d0;--ac2:#a371f7;--ok:#3fb950;--warn:#e5484d;--amber:#d29922}
body{background:var(--bg);color:var(--tx);font:14px/1.65 -apple-system,"Segoe UI","Microsoft YaHei",sans-serif;padding:28px 22px 70px;max-width:1560px;margin:0 auto}
h1{font-size:24px;font-weight:700;letter-spacing:.3px}
h2{font-size:18px;margin:34px 0 12px;padding-left:11px;border-left:4px solid var(--ac);font-weight:650}
h3{font-size:15px;margin:20px 0 9px;color:var(--ac)}
.sub{color:var(--tx2);font-size:13px;margin-top:7px;line-height:1.8}
code{background:#071120;padding:1.5px 6px;border-radius:4px;font:12.5px/1.5 "Cascadia Code",Consolas,monospace;color:#7ee3de}
pre{background:#071120;border:1px solid var(--bd);border-radius:9px;padding:13px 15px;overflow:auto;font:12.5px/1.65 "Cascadia Code",Consolas,monospace;color:#c6d4e8}
.card{background:var(--card);border:1px solid var(--bd);border-radius:12px;padding:17px 19px;margin:12px 0}
.grid{display:grid;gap:13px}
.g3{grid-template-columns:repeat(auto-fit,minmax(250px,1fr))}
.g4{grid-template-columns:repeat(auto-fit,minmax(196px,1fr))}
.kpi{background:var(--card2);border:1px solid var(--bd);border-radius:11px;padding:14px 16px}
.kpi .n{font-size:25px;font-weight:700;color:var(--ac);line-height:1.25}
.kpi .l{font-size:12px;color:var(--tx2);margin-top:3px}
table{width:100%;border-collapse:collapse;font-size:12.5px}
th,td{border:1px solid var(--bd);padding:6.5px 9px;text-align:left;vertical-align:top}
th{background:#0d1a2e;color:var(--ac);font-weight:600;position:sticky;top:0}
tbody tr:nth-child(even){background:#0e1a2b}
.tag{display:inline-block;padding:1px 7px;border-radius:5px;font-size:11.5px;font-weight:600;margin-right:4px;white-space:nowrap}
.t-ok{background:rgba(63,185,80,.16);color:var(--ok);border:1px solid rgba(63,185,80,.4)}
.t-bad{background:rgba(229,72,77,.16);color:var(--warn);border:1px solid rgba(229,72,77,.4)}
.t-amb{background:rgba(210,153,34,.16);color:var(--amber);border:1px solid rgba(210,153,34,.4)}
.t-ac{background:rgba(56,214,208,.14);color:var(--ac);border:1px solid rgba(56,214,208,.4)}
.t-pu{background:rgba(163,113,247,.16);color:var(--ac2);border:1px solid rgba(163,113,247,.4)}
.verdict{border-left:5px solid var(--ac);background:linear-gradient(90deg,rgba(56,214,208,.08),transparent)}
.verdict.bad{border-left-color:var(--warn);background:linear-gradient(90deg,rgba(229,72,77,.08),transparent)}
.verdict.amb{border-left-color:var(--amber);background:linear-gradient(90deg,rgba(210,153,34,.08),transparent)}
details{background:var(--card2);border:1px solid var(--bd);border-radius:10px;margin:9px 0;padding:0}
details>summary{cursor:pointer;padding:11px 15px;font-weight:600;font-size:13.5px;list-style:none;display:flex;justify-content:space-between;gap:10px;flex-wrap:wrap}
details>summary::-webkit-details-marker{display:none}
details>summary:hover{background:#132340}
details>div{padding:2px 15px 15px}
.mono{font-family:"Cascadia Code",Consolas,monospace;font-size:12px}
.muted{color:var(--tx2)}
.wrap{overflow-x:auto}
.foot{margin-top:38px;padding-top:16px;border-top:1px solid var(--bd);color:var(--tx2);font-size:12px;line-height:1.9}
ul{margin:6px 0 6px 20px}li{margin:3px 0}
.hl{color:var(--ac);font-weight:600}
.bad-t{color:var(--warn);font-weight:600}
.amb-t{color:var(--amber);font-weight:600}
</style></head><body>
<h1>DSH 平台 · 项目架构全景图(细到功能点)</h1>
<p class="sub">生成时间 2026-09-21 08:2x · 仓库 <code>D:\github\dsh_shenxian</code> · 基线 <code>HEAD=1242d07</code>
 · 采集方式:<span class="hl">静态扫描全仓 100 个 .ts</span>(脚本口径与 <code>scripts/check-layering.mjs</code> 对齐)+ <code>npm run check:layering --json</code>
<br>⚠️ 本图为**只读分析产物**:未修改任何生产代码、未部署、未重启。</p>
<h2>一、规模与分层总览</h2>
<div class="grid g4">
<div class="kpi"><div class="n">100</div><div class="l">src/ 下 .ts 文件</div></div>
<div class="kpi"><div class="n">35,184</div><div class="l">总行数</div></div>
<div class="kpi"><div class="n">78</div><div class="l">HTTP 功能点(路由条目)</div></div>
<div class="kpi"><div class="n">13</div><div class="l">数据表</div></div>
<div class="kpi"><div class="n">5</div><div class="l">分层违规(全部在基线内)</div></div>
<div class="kpi"><div class="n">0</div><div class="l">本轮新增违规</div></div>
<div class="kpi"><div class="n">0</div><div class="l">② 领域层文件(空缺)</div></div>
<div class="kpi"><div class="n">1</div><div class="l">未归类文件</div></div>
</div>
<h2>二、分层模块图(依赖方向)</h2>
<div class="wrap"><svg viewBox="0 0 928 450" style="width:100%;min-width:880px">
<defs>
<marker id="ar" markerWidth="9" markerHeight="9" refX="5" refY="4.5" orient="auto"><path d="M0,0 L9,4.5 L0,9 z" fill="#38d6d0"/></marker>
<marker id="ar2" markerWidth="9" markerHeight="9" refX="5" refY="4.5" orient="auto"><path d="M0,0 L9,4.5 L0,9 z" fill="#e5484d"/></marker>
</defs>
<rect x="0" y="0" width="928" height="450" fill="#0b1424"/>
<text x="16" y="14" fill="#93a4be" font-size="11.5">合法方向 ①→②→③→④(青色箭头,278 条实际 import 边) · 违规回指(红色箭头,5 条) · ② 领域层为 0 文件</text>
<rect x="16" y="26" width="896" height="74" rx="10" fill="#0e1a2c" stroke="#38d6d0" stroke-opacity=".55"/>
<text x="32" y="53" fill="#38d6d0" font-size="14.5" font-weight="700">① 入口层 Entry</text>
<text x="32" y="74" fill="#93a4be" font-size="11.5" font-family="Consolas,monospace">src/cli.ts · src/web/**(server/routes/middleware)</text>
<text x="32" y="92" fill="#6f8199" font-size="11">HTTP 路由 · 鉴权中间件 · 静态资源 · HTML 注入</text>
<text x="760" y="60" fill="#38d6d0" font-size="19" font-weight="700" text-anchor="middle">32</text>
<text x="760" y="76" fill="#93a4be" font-size="10.5" text-anchor="middle">files</text>
<text x="858" y="60" fill="#38d6d0" font-size="19" font-weight="700" text-anchor="middle">8,520</text>
<text x="858" y="76" fill="#93a4be" font-size="10.5" text-anchor="middle">lines</text><rect x="16" y="118" width="896" height="74" rx="10" fill="#0e1a2c" stroke="#a371f7" stroke-opacity=".55"/>
<text x="32" y="145" fill="#a371f7" font-size="14.5" font-weight="700">② 领域层 Domain</text>
<text x="32" y="166" fill="#93a4be" font-size="11.5" font-family="Consolas,monospace">src/domain/** —— 当前为空(P1 未做)</text>
<text x="32" y="184" fill="#6f8199" font-size="11">业务规则本应在此层,现实被写在 ① 与 ③</text>
<text x="760" y="152" fill="#a371f7" font-size="19" font-weight="700" text-anchor="middle">0</text>
<text x="760" y="168" fill="#93a4be" font-size="10.5" text-anchor="middle">files</text>
<text x="858" y="152" fill="#a371f7" font-size="19" font-weight="700" text-anchor="middle">0</text>
<text x="858" y="168" fill="#93a4be" font-size="10.5" text-anchor="middle">lines</text><rect x="16" y="210" width="896" height="74" rx="10" fill="#0e1a2c" stroke="#d29922" stroke-opacity=".55"/>
<text x="32" y="237" fill="#d29922" font-size="14.5" font-weight="700">③ 能力层 Capability</text>
<text x="32" y="258" fill="#93a4be" font-size="11.5" font-family="Consolas,monospace">src/{supervisor,db,fs,worker,net,nginx}/**</text>
<text x="32" y="276" fill="#6f8199" font-size="11">实例编排 · 数据持久化 · 文件系统 · 覆盖网络/中继 · WORKER 代理</text>
<text x="760" y="244" fill="#d29922" font-size="19" font-weight="700" text-anchor="middle">63</text>
<text x="760" y="260" fill="#93a4be" font-size="10.5" text-anchor="middle">files</text>
<text x="858" y="244" fill="#d29922" font-size="19" font-weight="700" text-anchor="middle">25,721</text>
<text x="858" y="260" fill="#93a4be" font-size="10.5" text-anchor="middle">lines</text><rect x="16" y="302" width="896" height="74" rx="10" fill="#0e1a2c" stroke="#3fb950" stroke-opacity=".55"/>
<text x="32" y="329" fill="#3fb950" font-size="14.5" font-weight="700">④ 基础层 Foundation</text>
<text x="32" y="350" fill="#93a4be" font-size="11.5" font-family="Consolas,monospace">src/{config,crypto,isolation,index}.ts</text>
<text x="32" y="368" fill="#6f8199" font-size="11">配置 · 加密 · 沙箱隔离 · 进程入口</text>
<text x="760" y="336" fill="#3fb950" font-size="19" font-weight="700" text-anchor="middle">4</text>
<text x="760" y="352" fill="#93a4be" font-size="10.5" text-anchor="middle">files</text>
<text x="858" y="336" fill="#3fb950" font-size="19" font-weight="700" text-anchor="middle">878</text>
<text x="858" y="352" fill="#93a4be" font-size="10.5" text-anchor="middle">lines</text>
<text x="770" y="16" fill="#6f8199" font-size="10.5" text-anchor="middle">文件数</text>
<text x="862" y="16" fill="#6f8199" font-size="10.5" text-anchor="middle">行数</text>
<line x1="760" y1="109" x2="760" y2="118" stroke="#38d6d0" stroke-width="2" marker-end="url(#ar)"/><line x1="798" y1="118" x2="798" y2="109" stroke="#e5484d" stroke-width="2" marker-end="url(#ar2)"/><line x1="760" y1="201" x2="760" y2="210" stroke="#38d6d0" stroke-width="2" marker-end="url(#ar)"/><line x1="798" y1="210" x2="798" y2="201" stroke="#e5484d" stroke-width="2" marker-end="url(#ar2)"/><line x1="760" y1="293" x2="760" y2="302" stroke="#38d6d0" stroke-width="2" marker-end="url(#ar)"/><line x1="798" y1="302" x2="798" y2="293" stroke="#e5484d" stroke-width="2" marker-end="url(#ar2)"/>
<text x="16" y="436" fill="#93a4be" font-size="11.5">未归类(必须先定层):src/platform-paths.ts</text>
</svg></div>
<p class="sub">四层由 <code>docs/architecture.md §1</code> 定义;层归属**只按目录判**(不做语义推断)。② 领域层自 2026-09-16 立规则起至今仍为 <span class="bad-t">0 文件</span> —— 这是本图唯一的结构性空缺。</p>
<h3>层间 import 矩阵(实测)</h3>
<div class="wrap"><table><thead><tr><th>源 \ 目标</th><th>①入口</th><th>②领域</th><th>③能力</th><th>④基础</th><th>合计</th></tr></thead><tbody><tr><td class="mono">①入口</td><td class='mono'><span class="hl">54</span></td><td class='mono'><span class="muted">0</span></td><td class='mono'><span class="hl">52</span></td><td class='mono'><span class="hl">8</span></td><td class="mono">114</td></tr><tr><td class="mono">②领域</td><td class='mono'><span class="muted">0</span></td><td class='mono'><span class="muted">0</span></td><td class='mono'><span class="muted">0</span></td><td class='mono'><span class="muted">0</span></td><td class="mono">0</td></tr><tr><td class="mono">③能力</td><td class='mono'><span class="bad-t">5 ⛔</span></td><td class='mono'><span class="muted">0</span></td><td class='mono'><span class="hl">153</span></td><td class='mono'><span class="hl">6</span></td><td class="mono">164</td></tr><tr><td class="mono">④基础</td><td class='mono'><span class="muted">0</span></td><td class='mono'><span class="muted">0</span></td><td class='mono'><span class="muted">0</span></td><td class='mono'><span class="muted">0</span></td><td class="mono">0</td></tr></tbody></table></div><p class="sub">判据:目标层号 &lt; 源层号 ⇒ 违规(红)。矩阵合计 = 278 条层间边(= 全仓相对 import 边总数,含跨层重复计数按"边"计一次)。</p>
<h3>现存违规明细(5 条 · 与基线逐条对应)</h3>
<p class="sub">基线文件 <code>scripts/layering-baseline.json</code>:棘轮(ratchet),**只许减不许增**;新增即令 <code>npm run verify</code> 失败。</p>
<div class="wrap"><table><thead><tr><th style="width:64px">规则</th><th style="width:290px">源(下层,违规方)</th><th style="width:290px">目标(上层)</th><th style="width:56px">行号</th><th style="width:120px">方向</th><th>arch.md §5.1 记载的修法方向</th></tr></thead><tbody><tr><td><span class="tag t-bad">R1</span></td><td class="mono">src/fs/local-user-fs.ts</td><td class="mono">src/web/middleware/fs-guard.ts</td><td class="mono">13</td><td class="mono muted">③能力 → ①入口</td><td class="muted">路径守卫 = 领域规则 ⇒ 归 src/domain/</td></tr><tr><td><span class="tag t-bad">R1</span></td><td class="mono">src/fs/remote-user-fs.ts</td><td class="mono">src/web/middleware/fs-guard.ts</td><td class="mono">18</td><td class="mono muted">③能力 → ①入口</td><td class="muted">路径守卫 = 领域规则 ⇒ 归 src/domain/</td></tr><tr><td><span class="tag t-bad">R1</span></td><td class="mono">src/fs/workspace.ts</td><td class="mono">src/web/middleware/fs-guard.ts</td><td class="mono">14</td><td class="mono muted">③能力 → ①入口</td><td class="muted">路径守卫 = 领域规则 ⇒ 归 src/domain/</td></tr><tr><td><span class="tag t-bad">R1</span></td><td class="mono">src/supervisor/proxy.ts</td><td class="mono">src/web/auth.ts</td><td class="mono">19</td><td class="mono muted">③能力 → ①入口</td><td class="muted">纯函数 ⇒ 下沉到基础层</td></tr><tr><td><span class="tag t-bad">R1</span></td><td class="mono">src/supervisor/proxy.ts</td><td class="mono">src/web/middleware/authn.ts</td><td class="mono">20</td><td class="mono muted">③能力 → ①入口</td><td class="muted">会话校验属能力 ⇒ 下沉能力层</td></tr></tbody></table></div>
<h2>三、关键调用链(沿真实 import 边展开)</h2>
<p class="sub">每条链从入口文件出发,列首层依赖与二跳新增模块 —— 用于回答"改一个功能要读几个模块"。</p>
<details><summary><span class="mono">src/web/routes/auth.ts</span>
<span class="muted" style="font-weight:400">直连 11 · 二跳累计 7 个模块</span></summary>
<div class="grid g3">
<div><div class="tag t-ac">首层依赖</div><div class="mono" style="margin:2px 0">→ src/crypto.ts</div><div class="mono" style="margin:2px 0">→ src/db/types.ts</div><div class="mono" style="margin:2px 0">→ src/fs/workspace.ts</div><div class="mono" style="margin:2px 0">→ src/web/auth.ts</div><div class="mono" style="margin:2px 0">→ src/web/email-code.ts</div><div class="mono" style="margin:2px 0">→ src/web/home-files.ts</div><div class="mono" style="margin:2px 0">→ src/web/locale-pref.ts</div><div class="mono" style="margin:2px 0">→ src/web/middleware/authn.ts</div><div class="mono" style="margin:2px 0">→ src/web/model-catalog.ts</div><div class="mono" style="margin:2px 0">→ src/web/model-landing.ts</div><div class="mono" style="margin:2px 0">→ src/web/turnstile.ts</div></div>
<div><div class="tag t-pu">二跳新增</div><div class="mono" style="margin:2px 0">→ src/config.ts</div><div class="mono" style="margin:2px 0">→ src/db/adapter.ts</div><div class="mono" style="margin:2px 0">→ src/net/reachability.ts</div><div class="mono" style="margin:2px 0">→ src/web/dsh-install.ts</div><div class="mono" style="margin:2px 0">→ src/web/mail.ts</div><div class="mono" style="margin:2px 0">→ src/web/middleware/fs-guard.ts</div><div class="mono" style="margin:2px 0">→ src/web/register-guard.ts</div></div>
</div></details><details><summary><span class="mono">src/web/routes/dsh.ts</span>
<span class="muted" style="font-weight:400">直连 8 · 二跳累计 8 个模块</span></summary>
<div class="grid g3">
<div><div class="tag t-ac">首层依赖</div><div class="mono" style="margin:2px 0">→ src/fs/workspace.ts</div><div class="mono" style="margin:2px 0">→ src/supervisor/orchestrator.ts</div><div class="mono" style="margin:2px 0">→ src/supervisor/patch.ts</div><div class="mono" style="margin:2px 0">→ src/supervisor/proxy.ts</div><div class="mono" style="margin:2px 0">→ src/supervisor/session-preset.ts</div><div class="mono" style="margin:2px 0">→ src/supervisor/spawner.ts</div><div class="mono" style="margin:2px 0">→ src/web/middleware/authn.ts</div><div class="mono" style="margin:2px 0">→ src/web/routes/desktop.ts</div></div>
<div><div class="tag t-pu">二跳新增</div><div class="mono" style="margin:2px 0">→ src/config.ts</div><div class="mono" style="margin:2px 0">→ src/db/types.ts</div><div class="mono" style="margin:2px 0">→ src/fs/user-fs.ts</div><div class="mono" style="margin:2px 0">→ src/supervisor/crash-policy.ts</div><div class="mono" style="margin:2px 0">→ src/supervisor/firewall.ts</div><div class="mono" style="margin:2px 0">→ src/supervisor/spawn.ts</div><div class="mono" style="margin:2px 0">→ src/web/auth.ts</div><div class="mono" style="margin:2px 0">→ src/web/middleware/fs-guard.ts</div></div>
</div></details><details><summary><span class="mono">src/web/routes/business-plugins.ts</span>
<span class="muted" style="font-weight:400">直连 4 · 二跳累计 4 个模块</span></summary>
<div class="grid g3">
<div><div class="tag t-ac">首层依赖</div><div class="mono" style="margin:2px 0">→ src/fs/workspace.ts</div><div class="mono" style="margin:2px 0">→ src/web/middleware/authn.ts</div><div class="mono" style="margin:2px 0">→ src/web/plugin-compat.ts</div><div class="mono" style="margin:2px 0">→ src/web/security-scan.ts</div></div>
<div><div class="tag t-pu">二跳新增</div><div class="mono" style="margin:2px 0">→ src/db/types.ts</div><div class="mono" style="margin:2px 0">→ src/web/auth.ts</div><div class="mono" style="margin:2px 0">→ src/web/dsh-install.ts</div><div class="mono" style="margin:2px 0">→ src/web/middleware/fs-guard.ts</div></div>
</div></details><details><summary><span class="mono">src/supervisor/proxy.ts</span>
<span class="muted" style="font-weight:400">直连 3 · 二跳累计 1 个模块</span></summary>
<div class="grid g3">
<div><div class="tag t-ac">首层依赖</div><div class="mono" style="margin:2px 0">→ src/supervisor/spawner.ts</div><div class="mono" style="margin:2px 0">→ src/web/auth.ts</div><div class="mono" style="margin:2px 0">→ src/web/middleware/authn.ts</div></div>
<div><div class="tag t-pu">二跳新增</div><div class="mono" style="margin:2px 0">→ src/db/types.ts</div></div>
</div></details><details><summary><span class="mono">src/net/relay/server.ts</span>
<span class="muted" style="font-weight:400">直连 5 · 二跳累计 1 个模块</span></summary>
<div class="grid g3">
<div><div class="tag t-ac">首层依赖</div><div class="mono" style="margin:2px 0">→ src/net/relay/identity.ts</div><div class="mono" style="margin:2px 0">→ src/net/relay/jitter.ts</div><div class="mono" style="margin:2px 0">→ src/net/relay/keys.ts</div><div class="mono" style="margin:2px 0">→ src/net/relay/network.ts</div><div class="mono" style="margin:2px 0">→ src/net/relay/wire.ts</div></div>
<div><div class="tag t-pu">二跳新增</div><div class="mono" style="margin:2px 0">→ src/net/relay/directory.ts</div></div>
</div></details>
<h2>四、目录规模与职责</h2>
<div class="wrap"><table><thead><tr><th style="width:280px">目录</th><th style="width:90px">文件数</th><th style="width:100px">行数</th><th style="width:90px">层归属</th><th>说明</th></tr></thead><tbody><tr><td class="mono">src/net/relay</td><td class="mono">21</td><td class="mono">11,585</td><td class="mono">③能力</td><td class="muted">自研中继:服务端 / 客户端 / 目录 / 身份 / 切流 / 内容块级寻址 / 直连打洞</td></tr><tr><td class="mono">src/web/routes</td><td class="mono">13</td><td class="mono">4,142</td><td class="mono">①入口</td><td class="muted">HTTP 路由 = 事实上的业务层(②领域层为空导致)</td></tr><tr><td class="mono">src/db</td><td class="mono">10</td><td class="mono">3,987</td><td class="mono">③能力</td><td class="muted">schema · types · repo · pg · adapter(SQLite↔PG 双写)</td></tr><tr><td class="mono">src/supervisor</td><td class="mono">11</td><td class="mono">3,983</td><td class="mono">③能力</td><td class="muted">实例监督:代理 / 编排 / 注入 / 崩溃策略</td></tr><tr><td class="mono">src/web</td><td class="mono">15</td><td class="mono">3,862</td><td class="mono">①入口</td><td class="muted">服务装配 · 鉴权 · 国际化 · 静态资源 · 注入</td></tr><tr><td class="mono">src/net/relay/content</td><td class="mono">6</td><td class="mono">2,388</td><td class="mono">③能力</td><td class="muted">内容分发(块级寻址 · 加解密 · 运行时)</td></tr><tr><td class="mono">src</td><td class="mono">6</td><td class="mono">1,337</td><td class="mono">未归类</td><td class="muted">入口 cli.ts · 基础层 4 件 · platform-paths</td></tr><tr><td class="mono">src/net/relay/direct</td><td class="mono">3</td><td class="mono">1,327</td><td class="mono">③能力</td><td class="muted">P2P 直连(打洞)</td></tr><tr><td class="mono">src/worker</td><td class="mono">3</td><td class="mono">1,317</td><td class="mono">③能力</td><td class="muted">多机 Worker 代理与 provisioner</td></tr><tr><td class="mono">src/fs</td><td class="mono">6</td><td class="mono">796</td><td class="mono">③能力</td><td class="muted">用户卷:本地 / 远端 UserFs + 路径守卫</td></tr><tr><td class="mono">src/net</td><td class="mono">2</td><td class="mono">292</td><td class="mono">③能力</td><td class="muted">可达性与会合(覆盖网络 S0)</td></tr><tr><td class="mono">src/web/middleware</td><td class="mono">3</td><td class="mono">122</td><td class="mono">①入口</td><td class="muted">鉴权 / FS 守卫中间件(被 ③ 反向依赖)</td></tr><tr><td class="mono">src/nginx</td><td class="mono">1</td><td class="mono">46</td><td class="mono">③能力</td><td class="muted">站点配置生成</td></tr></tbody></table></div>
<h2>五、大文件与扇入(迭代阻力信号)</h2>
<p class="sub">判据:**大文件 + 高扇入 = 迭代阻力信号**。下方"被依赖" = 该文件被仓内其他文件 import 的边数。</p>
<div class="wrap"><table><thead><tr><th style="width:60px">行数</th><th style="width:300px">文件</th><th>相对规模</th><th style="width:100px">被依赖</th><th>风险判读(阈值 600 行)</th></tr></thead><tbody><tr><td class="mono">2472</td><td class="mono">src/net/relay/server.ts</td><td><div style="background:#0b1424;border-radius:4px;height:13px"><div style="width:100%;height:13px;border-radius:4px;background:linear-gradient(90deg,#38d6d0,#a371f7)"></div></div></td><td class="mono">3</td><td><span class="tag t-bad">高</span> <span class="muted">单文件超 1,200 行:改一处需通读全文,context 成本高</span></td></tr><tr><td class="mono">1786</td><td class="mono">src/net/relay/client.ts</td><td><div style="background:#0b1424;border-radius:4px;height:13px"><div style="width:72%;height:13px;border-radius:4px;background:linear-gradient(90deg,#38d6d0,#a371f7)"></div></div></td><td class="mono">6</td><td><span class="tag t-bad">高</span> <span class="muted">单文件超 1,200 行:改一处需通读全文,context 成本高</span></td></tr><tr><td class="mono">1719</td><td class="mono">src/supervisor/orchestrator.ts</td><td><div style="background:#0b1424;border-radius:4px;height:13px"><div style="width:70%;height:13px;border-radius:4px;background:linear-gradient(90deg,#38d6d0,#a371f7)"></div></div></td><td class="mono">4</td><td><span class="tag t-bad">高</span> <span class="muted">单文件超 1,200 行:改一处需通读全文,context 成本高</span></td></tr><tr><td class="mono">1296</td><td class="mono">src/web/server.ts</td><td><div style="background:#0b1424;border-radius:4px;height:13px"><div style="width:52%;height:13px;border-radius:4px;background:linear-gradient(90deg,#38d6d0,#a371f7)"></div></div></td><td class="mono">1</td><td><span class="tag t-bad">高</span> <span class="muted">单文件超 1,200 行:改一处需通读全文,context 成本高</span></td></tr><tr><td class="mono">974</td><td class="mono">src/db/repo.ts</td><td><div style="background:#0b1424;border-radius:4px;height:13px"><div style="width:39%;height:13px;border-radius:4px;background:linear-gradient(90deg,#38d6d0,#a371f7)"></div></div></td><td class="mono">1</td><td><span class="tag t-amb">中</span> <span class="muted">超 700 行:建议按职责拆分(未做,P1 范畴)</span></td></tr><tr><td class="mono">974</td><td class="mono">src/db/pg.ts</td><td><div style="background:#0b1424;border-radius:4px;height:13px"><div style="width:39%;height:13px;border-radius:4px;background:linear-gradient(90deg,#38d6d0,#a371f7)"></div></div></td><td class="mono">1</td><td><span class="tag t-amb">中</span> <span class="muted">超 700 行:建议按职责拆分(未做,P1 范畴)</span></td></tr><tr><td class="mono">846</td><td class="mono">src/net/relay/directory.ts</td><td><div style="background:#0b1424;border-radius:4px;height:13px"><div style="width:34%;height:13px;border-radius:4px;background:linear-gradient(90deg,#38d6d0,#a371f7)"></div></div></td><td class="mono">9</td><td><span class="tag t-amb">中</span> <span class="muted">超 700 行:建议按职责拆分(未做,P1 范畴)</span></td></tr><tr><td class="mono">793</td><td class="mono">src/config.ts</td><td><div style="background:#0b1424;border-radius:4px;height:13px"><div style="width:32%;height:13px;border-radius:4px;background:linear-gradient(90deg,#38d6d0,#a371f7)"></div></div></td><td class="mono">8</td><td><span class="tag t-amb">中</span> <span class="muted">超 700 行:建议按职责拆分(未做,P1 范畴)</span></td></tr><tr><td class="mono">791</td><td class="mono">src/supervisor/proxy.ts</td><td><div style="background:#0b1424;border-radius:4px;height:13px"><div style="width:32%;height:13px;border-radius:4px;background:linear-gradient(90deg,#38d6d0,#a371f7)"></div></div></td><td class="mono">2</td><td><span class="tag t-amb">中</span> <span class="muted">超 700 行:建议按职责拆分(未做,P1 范畴)</span></td></tr><tr><td class="mono">743</td><td class="mono">src/web/routes/business-plugins.ts</td><td>
<h3>被依赖最多的模块(高扇入)</h3>
<div class="wrap"><table><thead><tr><th style="width:70px">被依赖</th><th style="width:340px">文件</th><th style="width:120px">层</th><th>含义</th></tr></thead><tbody>
<tr><td class="mono">17</td><td class="mono">src/net/relay/network.ts</td><td class="mono">③能力</td><td class="muted">改动影响面最广,需交叉验证</td></tr><tr><td class="mono">14</td><td class="mono">src/fs/workspace.ts</td><td class="mono">③能力</td><td class="muted">改动影响面最广,需交叉验证</td></tr><tr><td class="mono">14</td><td class="mono">src/net/relay/identity.ts</td><td class="mono">③能力</td><td class="muted">改动影响面最广,需交叉验证</td></tr><tr><td class="mono">13</td><td class="mono">src/web/middleware/authn.ts</td><td class="mono">①入口</td><td class="muted">改动影响面最广,需交叉验证</td></tr><tr><td class="mono">11</td><td class="mono">src/db/types.ts</td><td class="mono">③能力</td><td class="muted">改动影响面最广,需交叉验证</td></tr><tr><td class="mono">9</td><td class="mono">src/db/adapter.ts</td><td class="mono">③能力</td><td class="muted">影响面中等</td></tr><tr><td class="mono">9</td><td class="mono">src/net/relay/directory.ts</td><td class="mono">③能力</td><td class="muted">影响面中等</td></tr><tr><td class="mono">8</td><td class="mono">src/config.ts</td><td class="mono">④基础</td><td class="muted">影响面中等</td></tr><tr><td class="mono">8</td><td class="mono">src/net/relay/switcher.ts</td><td class="mono">③能力</td><td class="muted">影响面中等</td></tr><tr><td class="mono">7</td><td class="mono">src/fs/user-fs.ts</td><td class="mono">③能力</td><td class="muted">影响面中等</td></tr><tr><td class="mono">7</td><td class="mono">src/supervisor/spawner.ts</td><td class="mono">③能力</td><td class="muted">影响面中等</td></tr><tr><td class="mono">6</td><td class="mono">src/net/reachability.ts</td><td class="mono">③能力</td><td class="muted">影响面中等</td></tr><tr><td class="mono">6</td><td class="mono">src/net/relay/content/crypto.ts</td><td class="mono">③能力</td><td class="muted">影响面中等</td></tr><tr><td class="mono">6</td><td class="mono">src/net/relay/direct/candidate.ts</td><td class="mono">③能力</td><td class="muted">影响面中等</td></tr>
</tbody></table></div>
<h2>六、功能点索引(入口路由 → 处理层 → 依赖模块 → 数据表 → 前端页面)</h2>
<p class="sub">共 <span class="hl">78</span> 个功能点,分布在 <span class="hl">12</span> 个路由文件中。前端页面为按 API 前缀反查所得(<code>/api/…</code> 字面量匹配),"—" 表示无前端页面直接调用(如登录态内部调用、Worker 侧调用)。<br>「数据表」列 = 该路由文件内<b>直接出现</b>的表名(<code>'表名'</code> 字面量或 SQL <code>FROM/JOIN/UPDATE/INTO</code> 之后);经 <code>db/repo.ts</code> 间接访问、以及路由委托给 <code>supervisor/*</code> 后由能力层落库的,不在本列体现(<b>宁缺不误报</b>)。</p>
<h3>认证与注册 <span class="muted" style="font-weight:400;font-size:12.5px">· 10 个功能点</span></h3><div class="wrap"><table><thead><tr><th style="width:74px">方法</th><th style="width:250px">入口路由</th><th style="width:196px">处理层(文件 · 行数)</th><th>依赖模块</th><th style="width:150px">数据表</th><th style="width:130px">前端页面</th></tr></thead><tbody><tr><td><span class="tag t-ac">POST</span></td><td class="mono">/api/auth/login</td><td class="mono">auth.ts<div class="muted">672 行 · 本文件 15 个路由</div></td><td><div class="mono muted">crypto.ts</div><div class="mono muted">types.ts</div><div class="mono muted">workspace.ts</div><div class="mono muted">auth.ts</div><div class="mono muted">email-code.ts</div><div class="mono muted">… 另 6 个</div><div class="mono">supervisor.restartAllMains()</div><div class="mono">supervisor.restartMain()</div></td><td><span class="muted">—</span></td><td class="mono muted">admin.html, login.html</td></tr><tr><td><span class="tag t-ac">POST</span></td><td class="mono">/api/auth/logout</td><td class="mono">auth.ts<div class="muted">672 行 · 本文件 15 个路由</div></td><td><div class="mono muted">crypto.ts</div><div class="mono muted">types.ts</div><div class="mono muted">workspace.ts</div><div class="mono muted">auth.ts</div><div class="mono muted">email-code.ts</div><div class="mono muted">… 另 6 个</div><div class="mono">supervisor.restartAllMains()</div><div class="mono">supervisor.restartMain()</div></td><td><span class="muted">—</span></td><td class="mono muted">admin.html, portal.html</td></tr><tr><td><span class="tag t-ac">GET</span></td><td class="mono">/api/auth/me</td><td class="mono">auth.ts<div class="muted">672 行 · 本文件 15 个路由</div></td><td><div class="mono muted">crypto.ts</div><div class="mono muted">types.ts</div><div class="mono muted">workspace.ts</div><div class="mono muted">auth.ts</div><div class="mono muted">email-code.ts</div><div class="mono muted">… 另 6 个</div><div class="mono">supervisor.restartAllMains()</div><div class="mono">supervisor.restartMain()</div></td><td><span class="muted">—</span></td><td class="mono muted">admin.html, index.html, portal.html</td></tr><tr><td><span class="tag t-ac">POST</span></td><td class="mono">/api/auth/register</td><td class="mono">auth.ts<div class="muted">672 行 · 本文件 15 个路由</div></td><td><div class="mono muted">crypto.ts</div><div class="mono muted">types.ts</div><div class="mono muted">workspace.ts</div><div class="mono muted">auth.ts</div><div class="mono muted">email-code.ts</div><div class="mono muted">… 另 6 个</div><div class="mono">supervisor.restartAllMains()</div><div class="mono">supervisor.restartMain()</div></td><td><span class="muted">—</span></td><td class="mono muted">register.html</td></tr><tr><td><span class="tag t-ac">GET</span></td><td class="mono">/api/auth/register/config</td><td class="mono">auth.ts<div class="muted">672 行 · 本文件 15 个路由</div></td><td><div class="mono muted">crypto.ts</div><div class="mono muted">types.ts</div><div class="mono muted">workspace.ts</div><div class="mono muted">auth.ts</div><div class="mono muted">email-code.ts</div><div class="mono muted">… 另 6 个</div><div class="mono">supervisor.restartAllMains()</div><div class="mono">supervisor.restartMain()</div></td><td><span class="muted">—</span></td><td class="mono muted">register.html</td></tr><tr><td><span class="tag t-ac">POST</span></td><td class="mono">/api/auth/register/email-code</td><td class="mono">auth.ts<div class="muted">672 行 · 本文件 15 个路由</div></td><td><div class="mono muted">crypto.ts</div><div class="mono muted">types.ts</div><div class="mono muted">workspace.ts</div><div class="mono muted">auth.ts</div><div class="mono muted">email-code.ts</div><div class="mono muted">… 另 6 个</div><div class="mono">supervisor.restartAllMains()</div><div class="mono">supervisor.restartMain()</div></td><td><span class="muted">—</span></td><td class="mono muted">register.h
<h2>七、结论:本次修改出问题,是否由代码结构混乱导致?</h2>
<div class="card verdict">
<h3 style="margin-top:0">判定 — 分三问回答(每条结论附可复核证据)</h3>
<p><span class="tag t-ok">否</span> <b>问题 1:本次修改出问题,是否由代码结构混乱导致?</b></p>
<p class="sub" style="margin-bottom:0">本次两处线上问题(07:35 的 proxy 回归、以及此前的验收假绿)**真因都不是"结构混乱"**:
判据主体选错(<code>request.raw</code> vs <code>reply.raw</code>)属 <b>方法性</b>;拿 401 当通过属 <b>验收方法性</b>;高水位赶工属 <b>流程性</b>。
结构面在同一时期的实测数据反而是**守住了**的:见下方证据 1–3。</p>
</div>
<div class="card">
<h3 style="margin-top:0">证据 1 · 结构性:扩张期未走形,且被机器约束住</h3>
<div class="wrap"><table><thead><tr><th style="width:150px">时间</th><th style="width:110px">.ts 文件</th><th style="width:110px">行数</th><th style="width:150px">违规边</th><th>来源</th></tr></thead><tbody>
<tr><td class="mono">2026-09-16</td><td class="mono">58</td><td class="mono">14,053</td><td class="mono">5 条</td><td class="muted">docs/architecture.md §3 / §5.1(当时实测)</td></tr>
<tr><td class="mono">2026-09-21</td><td class="mono">100</td><td class="mono">35,184</td><td class="mono">5 条(<span class="hl">同一批边</span>)</td><td class="muted">本轮 <code>check-layering.mjs --json</code></td></tr>
</tbody></table></div>
<p class="sub">5 天内文件数 <b>+72%</b>、行数 <b>+150%</b>,而 R1/R3/R4 违规**一条未增**(新增违规 <code>added = []</code>)。⇒ 结论:<b>代码结构没有混乱</b>,且分层方向在高速扩张下被棘轮脚本守住了。</p>
<pre>$ node scripts/check-layering.mjs
=== 分层依赖检查(docs/architecture.md R1–R4)===
扫描:100 个 .ts|归属 ①32 ②0 ③63 ④4|未归类 1
⚠️ 未归类(新增目录必须先定层):src/platform-paths.ts
现存违规 5 条(其中基线内 5 条)
✅ 无新增违规</pre>
</div>
<div class="card">
<h3 style="margin-top:0">证据 2 · 三类成因逐条归因(每条带证据)</h3>
<div class="wrap"><table><thead><tr><th style="width:92px">类别</th><th style="width:230px">成因</th><th>可复核证据</th><th style="width:120px">是否本因</th></tr></thead><tbody>
<tr>
<td><span class="tag t-bad">方法性</span></td>
<td><b>判据主体选错</b><br><span class="muted">监听"请求流"而非"响应流"</span></td>
<td><span class="mono">src/supervisor/proxy.ts</span>:错误写法 <code>request.raw.on('close')</code> —— GET 请求体读完即触发,被误判为"客户端断开",进而掐死正常请求 ⇒ 用户侧 <b>499</b>。<br>
另:即便换主体,若保留条件 <code>|| reply.raw.destroyed</code>,因 <code>'close'</code> 触发时响应流通常已 destroyed ⇒ 条件恒真 ⇒ <b>修复静默失效</b>(本轮 harness 实测记于接续包「本棒状态」第 1 条)。</td>
<td><span class="tag t-bad">是</span></td></tr>
<tr>
<td><span class="tag t-bad">方法性</span></td>
<td><b>验收打错路径(假绿)</b></td>
<td>用 <code>curl</code> 拿到的 <b>401</b> 当通过判据 —— 而 401 由平台在进入 <code>proxyHttp</code> <b>之前</b>返回,<b>根本走不到被改的代码</b>。<br>
正解口径(已写入档案 146 §九):带有效 <code>sid</code> 走真实子域请求,核对 <b>200 + 响应字节数 &gt; 0</b>;或部署后回读 <code>/www/wwwlogs/ai1net.com.log</code> 确认该子域出现 200(仍 499 = 没修好)。</td>
<td><span class="tag t-bad">是</span></td></tr>
<tr>
<td><span class="tag t-amb">流程性</span></td>
<td><b>高水位赶工</b></td>
<td>产生该回归的会话以「水位 &gt;30 万强制收口」结束(接续包首行:<code>结束原因: 水位 >30 万强制收口</code>)⇒ 在上下文余量告急时改了 4 处 + 10 hunk 的行为敏感代码,没有留出回读 access log 的余量。</td>
<td><span class="tag t-amb">是(放大器)</span></td></tr>
<tr>
<td><span class="tag t-ok">结构性</span></td>
<td>分层越界 / 职责不清 / 耦合</td>
<td>实测:违规边 <b>5 条</b>,全部与 09-16 首跑<b>逐条相同</b>,且集中在一个既有位置(<code>proxy.ts</code> 反指 <code>web/auth.ts</code>、<code>fs/*</code> 反指 <code>web/middleware/fs-guard.ts</code>)。<br>
被本次改动碰到的文件不在这 5 条边上:<code>proxy.ts</code> 的两条违规 import(第 19/20 行)是<b>读会话与 cookie 的工具函数</b>,与本次改的 <code>proxyHttp</code> 流监听<b>无耦合</b>。</td>
<td><span class="tag t-ok">不是本因</span></td></tr>
</tbody></table></div>
<p class="sub">⇒ 三类成因中 <b>方法性 2 条 + 流程性 1 条</b>是本因;<b>结构性 0 条</b>。这与档案 146 §九 的记载一致,本轮把它从"单次事故结论"升级为"对全局的验证结论"。</p>
</div>
<div class="card verdict amb">
<h3 style="margin-top:0">问题 2:是否已影响迭代效率?<span class="tag t-amb">部分是,但不是"混乱"造成的</span></h3>
<p class="sub" style="margin:0 0 6px 0">判定:<b>有可量化的效率损耗</b>,但归因于<b>结构空缺(缺领域层)+ 大文件</b>,而非"结构混乱"。三项实测信号:</p>
<ol style="margin-left:20px">
<li><b>缺 ② 领域层 ⇒ 业务规则一分为三</b>。例:插件启用规则写在 <code>src/web/routes/business-plugins.ts</code>(743 行),规则另一半在 <code>src/supervisor/orchestrator.ts</code>(1,719 行)与 <code>src/db/repo.ts</code>(974 行)⇒ 改一条规则<b>需连读三处 ≈ 3,400 行</b>。此为 <code>architecture.md §4 P1</code> 明确记录的已知债(未整改,因影响 &gt;10 文件需先出清单)。</li>
<li><b>大文件密度</b>:&gt;1,200 行的单文件 <b>4 个</b>(<code>net/relay/server.ts</code> 2,472 / <code>net/relay/client.ts</code> 1,786 / <code>supervisor/orchestrator.ts</code> 1,719 / <code>web/server.ts</code> 1,296);&gt;700 行共 <b>11 个</b>。改一个功能点通常要打开其中一个的全文。</li>
<li><b>高扇入点集中</b>:<code>src/web/middleware/authn.ts</code> 等被 13+ 个文件依赖 ⇒ 改它需做跨模块回归。</li>
</ol>
<p class="sub" style="margin-bottom:0">⚠️ 但三者的代价是<b>"读得多、改得慢"</b>,属可预期的工程债;<b>不是</b>"改 A 崩 B"的不确定性。本次事故属后者,故不可归因于结构。</p>
</div>
<div class="card">
<h3 style="margin-top:0">判定汇总(一句话版)</h3>
<div class="wrap"><table><thead><tr><th style="width:290px">问题</th><th style="width:130px">结论</th><th>主因 / 依据</th></tr></thead><tbody>
<tr><td>本次修改出问题,是否由代码结构混乱导致?</td><td><span class="tag t-ok">否</span></td><td>主因 = <b>方法性</b>(判据主体错 + 验收假绿,2 条)+ <b>流程性</b>(高水位赶工,1 条放大器);结构性 0 条,见证据 2 第 4 行</td></tr>
<tr><td>结构上是否有真实的效率损耗?</td><td><span class="tag t-amb">有</span></td><td>缺 ② 领域层(0/100 文件)+ 大文件(&gt;700 行 11 个)+ 高扇入点,属<b>已知债且已登记在案</b>(architecture.md §3/§4)</td></tr>
<tr><td>分层纪律是否被破坏?</td><td><span class="tag t-ok">否</span></td><td>违规边 09-16 与 09-21 逐条相同(5→5),<code>added=[]</code>;扩张 +150% 行数未新增违规</td></tr>
<tr><td>本轮是否需要重构?</td><td><span class="tag t-ok">不需要</span></td><td>architecture.md §4 已定序:P1(补 domain 层)<b>不阻塞</b>当前功能迭代;且属行为敏感、&gt;10 文件 ⇒ 须先出清单。本阶段只读,不动</td></tr>
</tbody></table></div>
</div>
<h2>八、复核方式(任何人可复现本图全部结论)</h2>
<pre>cd /d/github/dsh_shenxian
node scripts/check-layering.mjs # 分层违规(机器结论,退出码 0 = 无新增)
node scripts/check-layering.mjs --json # 违规明细 + 未归类清单(本图证据 1 的原始输出)
find src -name '*.ts' -exec wc -l {} + | sort -rn | head # 大文件排名(本图第五节)
grep -n "from '\./" src/supervisor/proxy.ts # 验证 proxy.ts 的两条违规 import
wc -l src/web/routes/*.ts src/supervisor/*.ts src/db/repo.ts # 验证"改一条规则读三处"的行数</pre>
<p class="sub">采集脚本:<code>tmp/arch_panorama_build.py</code>(只读,不写仓库内任何文件) · 原始数据:<code>tmp/arch_panorama.json</code></p>
<div class="foot">
DSH 平台 · 项目架构全景排查(阶段 3)|只读分析,未改任何生产代码、未部署、未重启<br>
证据口径:<code>scripts/check-layering.mjs</code>(与 <code>docs/architecture.md</code> R1–R4 同源)· <code>docs/architecture.md §3/§5.1</code> · <code>dsh-server-docs/04-调整方案/146-*.md §九</code> · 接续包《实例恢复浮层改造 20260921》「本棒状态」<br>
基线 <code>HEAD=1242d07</code>|扫描 100 个 .ts / 35,184 行 / 78 个功能点 / 13 张表
</div>
</body></html>