mirror of
https://github.com/Sagit-chu/flvx.git
synced 2026-09-28 07:36:38 +08:00
9b98194a0a
- Add backend API for tunnel delete rule resolution (allow, deny, confirm) - Add contract tests for delete resolution endpoint - Add frontend API types and endpoints for delete resolution - Add tunnel delete resolution settings UI with resolution mode selector - Support per-tunnel and global delete resolution configuration
7.9 KiB
7.9 KiB
044 - 隧道删除时的规则依赖处理设计
Goal
- 删除隧道前识别关联规则,避免默认级联误删。
- 在隧道页提供两种处理方式:迁移规则到其他隧道,或连同规则一起删除。
- 第一阶段只覆盖单条隧道删除,先把核心交互和执行链路做稳。
Checklist
- 复核当前
tunnel.tsx删除交互与DeleteTunnelCascade行为。 - 梳理可复用的规则换隧道能力(
forward/batch-change-tunnel)。 - 产出前端交互、接口与执行链路设计。
- 明确第一阶段范围、异常处理与回滚要求。
Implementation Checklist
- 新增后端删除预检与带规则处理的删除接口。
- 在后端补齐规则迁移/失败明细/回滚链路。
- 接入前端隧道删除预检、替换/删除规则弹窗与结果展示。
- 运行定向测试并记录结果。
Current State
vite-frontend/src/pages/tunnel.tsx的单条删除当前直接调用/tunnel/delete,没有前置依赖检查。go-backend/internal/store/repo/repository_mutations.go里的DeleteTunnelCascade会直接删除该隧道下的forward、forward_port、user_tunnel、chain_tunnel等关联数据。vite-frontend/src/pages/forward.tsx已经有“批量换隧道”交互和/forward/batch-change-tunnel,但如果前端直接串联“先换规则、再删隧道”,中间任一步失败都会留下半完成状态,不适合作为删除流程的最终方案。
Proposed UX
- 点击隧道删除按钮后,前端先请求“删除预检”接口,不直接进入最终确认。
- 若关联规则数为
0,继续沿用当前简单确认弹框。 - 若关联规则数大于
0,改为展示“处理关联规则”弹框:- 顶部
Alert提示:隧道 "A" 正被 12 条规则使用。 - 展示前 5 条规则摘要:规则名、所属用户、入口端口;剩余规则用“还有 N 条未展开”提示即可。
- 提供
RadioGroup两个动作:替换到其他隧道(推荐,默认)删除这些规则
- 选择“替换到其他隧道”时显示
Select:- 数据源直接复用当前页已经加载的
tunnels。 - 仅显示
status === 1且id !== 当前隧道的选项。 - 若没有可选隧道,则禁用该选项并自动回退到“删除这些规则”。
- 数据源直接复用当前页已经加载的
- 确认按钮文案动态变化:
替换规则并删除隧道删除规则并删除隧道
- 顶部
- 提交时展示 loading 状态;成功后关闭弹框、刷新隧道列表并 toast 成功。
- 如果后端返回规则级失败明细,前端复用现有
BatchActionResultModal展示失败项,而不是只给一个通用 toast。
API Design
1. 删除预检
POST /api/v1/tunnel/delete-preview
Request:
{ "id": 12 }
Response:
{
"code": 0,
"msg": "",
"data": {
"tunnelId": 12,
"tunnelName": "HK-Entry",
"forwardCount": 12,
"sampleForwards": [
{
"id": 101,
"name": "web-1",
"userId": 9,
"userName": "alice",
"inPort": 443
}
]
}
}
sampleForwards只需要返回前 5 条,前端用forwardCount决定是否显示“更多”提示。- 预检只描述现状,不负责最终授权或一致性保证;真正提交删除时,后端必须再校验一次。
2. 带规则处理的删除
POST /api/v1/tunnel/delete-with-forwards
Request:
{
"id": 12,
"action": "replace",
"targetTunnelId": 18
}
或:
{
"id": 12,
"action": "delete_forwards"
}
Success response:
{
"code": 0,
"msg": "",
"data": {
"forwardCount": 12,
"migratedCount": 12,
"deletedForwardCount": 0,
"portAdjustedCount": 2
}
}
Failure response:
{
"code": -2,
"msg": "部分规则迁移失败",
"data": {
"successCount": 9,
"failCount": 3,
"failures": [
{
"id": 101,
"name": "web-1",
"reason": "目标隧道入口节点端口 443 已占用"
}
]
}
}
- 保持现有
/tunnel/delete不动,兼容旧调用和当前批量删除逻辑。 vite-frontend/src/pages/tunnel.tsx的单条删除新流程全部走新接口。
Backend Execution Strategy
delete-preview- 校验 tunnel 是否存在。
- 查询
forward.tunnel_id = 当前隧道的数量和前 5 条摘要。
delete-with-forwards- 再次查询依赖规则,避免 preview 与提交之间状态变化导致误判。
action = delete_forwards- 直接复用当前级联删除逻辑。
action = replace- 校验
targetTunnelId:存在、启用、且不等于当前隧道。 - 先对全部关联规则做一次前置校验:目标隧道入口节点、端口范围、端口冲突、监听 IP 约束。
- 全部校验通过后,再逐条迁移规则并同步运行时。
- 任一规则迁移失败时,返回失败明细并中止删除;对已迁移规则做回滚,保证用户感知为“要么都成功,要么都不删”。
- 校验
- 规则处理完成后,再删除隧道本身及非
forward关联数据。
Frontend Implementation Notes
vite-frontend/src/pages/tunnel.tsx- 新增删除预检 loading、依赖摘要、处理动作等 state。
- 复用现有
Modal,根据 preview 结果切换普通确认视图和依赖处理视图。 - 复用
Select、RadioGroup、Alert。 - 成功后继续沿用当前
setTunnels、setTunnelOrder、setSelectedIds清理逻辑。
vite-frontend/src/api/index.ts- 新增
previewTunnelDelete。 - 新增
deleteTunnelWithForwards。
- 新增
- 删除失败且返回批量明细时,复用
BatchActionResultModal,避免具体失败规则原因被 toast 吞掉。
Scope Decision
- 第一阶段只改“隧道页单条删除”。
批量删除隧道先保持现有“级联删除规则”行为和提示文案不变。- 如果第一阶段确认体验和后端回滚链路都稳定,再补第二阶段:批量删除时按每条隧道分别预检和处理。
Edge Cases
- 没有可替换隧道:只允许“删除这些规则”。
- 目标隧道在提交前被禁用或删除:后端返回明确错误,前端保留当前弹框和用户选择。
- preview 时没有规则、提交时新建了规则:以后端最终校验为准,返回需要重新处理的提示。
- 迁移时若原入口端口在目标隧道不可用,沿用现有“换隧道”语义:优先保留原端口,不可用时自动分配可用端口,并通过
portAdjustedCount给前端一个非阻塞提示。 - 第一阶段不自动补发目标隧道的
user_tunnel授权,先与现有“批量换隧道”语义保持一致;如果后续需要让用户也获得目标隧道的新增规则权限,再单独评估自动补授权。
Implementation Notes
- 后端新增
/api/v1/tunnel/delete-preview和/api/v1/tunnel/delete-with-forwards,单条隧道删除改为先预检再执行。 - 后端新增
/api/v1/tunnel/batch-delete-preview和/api/v1/tunnel/batch-delete-with-forwards,批量删除支持统一预检并选择“批量替换规则”或“批量删除规则”。 - 规则替换删除在后端先做端口/节点占用预检,再执行逐条迁移;执行阶段若任一规则失败,会回滚已迁移规则,并把失败明细返回给前端弹窗展示。
- 前端
tunnel.tsx删除弹窗已支持三种状态:预检中、普通删除确认、有依赖规则时的“替换/删除规则”决策视图。 - 批量删除弹窗现在会汇总每条选中隧道的依赖规则数量,并在批量替换失败时按“隧道级”返回失败原因,避免整批操作信息丢失。
Verification
cd go-backend && go test ./internal/http/handler/...cd go-backend && go test ./tests/contract/... -run 'TestTunnelDeletePreviewIncludesDependentRulesContract|TestTunnelDeleteWithForwardsDeleteActionRemovesTunnelAndRulesContract|TestTunnelDeleteWithForwardsReplaceReturnsFailureDetailsContract'cd vite-frontend && npm run build