Clash Config Store 是一个面向 Mihomo/Clash 的订阅编排与分发平台:统一管理上游订阅源、规则集、自定义配置和订阅链接,最终生成可下发的完整 YAML。
核心用户流:
Provider 订阅源 → CustomConfig / ConfigTemplate → Subscription → /sub/{token}
- 前端路由:
frontend/src/App.tsx - 侧栏导航:
frontend/src/components/layout/Sidebar.tsx - 页面目录:
frontend/src/pages - 前端 API 模块:
frontend/src/api - 中英文文案:
frontend/src/i18n/locales/zh.ts、frontend/src/i18n/locales/en.ts - 后端路由注册:
cmd/server/main.go - 后端模型:
internal/model - 后端处理器:
internal/handler - 后端业务逻辑:
internal/service - YAML 生成链路:
internal/service/subscription.go、internal/util/yaml.go
- 改管理页或空状态:先看目标页面的
frontend/src/pages/*.tsx,再补frontend/src/i18n/locales/*.ts。 - 新增前端页面:按
frontend/src/pages、frontend/src/api、frontend/src/App.tsx、frontend/src/components/layout/Sidebar.tsx、i18n 的顺序处理。 - 新增后端资源接口:按
internal/model、internal/handler、必要时internal/service、cmd/server/main.go的顺序处理。 - 改订阅生成结果:先读
internal/service/subscription.go和internal/util/yaml.go,再补或更新相关 Go 测试。 - 改自定义配置导入/导出:优先看
internal/handler/custom_config.go与frontend/src/api/custom-configs.ts。 - 改订阅详情流程:同时检查
frontend/src/pages/SubscriptionDetail.tsx、frontend/src/api/subscriptions.ts、internal/handler/subscription.go。
- 前端类型与构建:
cd frontend && npm run build - 后端测试:
go test ./... - YAML 生成或订阅下发相关改动:优先补充并运行相关 Go 单测。
CustomConfig的rule_provider_ids/hosted_rule_set_ids依赖当前实例数据库主键,跨实例示例导入不要直接携带这些 ID。Subscription.EnabledProviderIDs在后端以 JSON 文本存储,更新时注意序列化与反序列化逻辑。GET /sub/:token是公开下发入口,受 token 过期与访问限制影响;改动时避免破坏公开订阅兼容性。ConfigTemplate只负责顶层 mihomo 配置,proxies/proxy-groups/rules应主要由CustomConfig管理。
- 领域文件映射见
docs/project-index.yaml。 - 前端页面地图见
docs/architecture/frontend-map.md。 - 后端资源地图见
docs/architecture/backend-map.md。 - 订阅生成数据流见
docs/architecture/data-flow.md。
- UI 组件:页面级布局、按钮、表单控件等优先使用 Shadcn UI(
frontend/src/components/ui/),保持与现有 Tailwind 主题一致。 - 全局顶栏保存条(Context Save Bar):需要「未保存 + 放弃 + 保存」且不应占用
AppLayout右侧语言/主题/用户区域时,使用ContextSaveBar+useRegisterContextSaveBar;页面卸载或enabled: false时必须自动注销,避免污染其他路由。扩展操作通过注册项里的extraActions(显示在「放弃」左侧),勿在ContextSaveBar.tsx内写死业务逻辑。 - 路由与
useBlocker:应用入口使用createBrowserRouter+RouterProvider(非BrowserRouter),以便在需要时用 React Router 的useBlocker拦截未保存离开。 - 注册方互斥:同一时间仅保留一个保存条注册方;多页面同时注册时以后注册者为准,新增场景前先评估是否改用局部 UI。