下面这份你可以直接丢给 Codex。 我把我们刚刚聊出来的**最终拍板结论**和**完整实现方案**都整理进去了。 --- # sub-provider 重构方案(最终版,完整 YAML 路线) ## 1. 最终结论 本项目后续重构,采用以下最终选择: ### 对外输出 * **统一输出单个完整 YAML** * 不强依赖客户端支持 `rule-providers` / `proxy-providers` * 目标是优先保证: * 兼容性 * 可调试性 * 易分发 * 易维护 ### 对内实现 * 内部仍然采用**模块化**设计 * 在 sub-provider 内部完成: * 源拉取与缓存 * 节点解析与标准化 * 节点筛选、重命名、去重 * 规则模块组合 * 策略组装配 * DNS / TUN / 通用配置拼装 * 最终完整 YAML 渲染 ### 规则存储方式 * **规则正文继续放项目文件** * 采用类似 ACL4SSR 的维护方式: * 一个类别的规则放一个文件 * 规则文件便于 Git 管理、diff、回滚、手工维护 * 不把 ACL4SSR 大量规则逐条入库 ### 规则组合与面板配置 * **规则的组合关系、启用状态、绑定的策略组、顺序、参数等放 SQLite** * 面板配置的是: * 选哪些规则模块 * 每个模块绑定哪个策略组 * 模块顺序 * 模块参数 * profile 配置 * 源配置 * 少量 prepend / append 自定义规则 ### 数据库选择 * **默认数据库:SQLite** * 原因: * 当前项目是单服务、轻量配置中心、生成器型应用 * SQLite 部署和迁移成本最低 * 最适合当前阶段快速落地 * 代码层要保留未来切 PostgreSQL 的能力: * 使用 SQLAlchemy * 使用 Alembic * 用 `DATABASE_URL` 配置数据库连接 * 当前不推荐 Mongo 作为主库 * 当前不优先推荐 MySQL --- ## 2. 目标 将现有 Python sub-provider 项目重构为一个: * 可面板管理 * 配置解耦 * 规则模块化 * 输出完整 YAML * 可缓存 * 可预览 * 可追踪生成结果 的配置生成系统。 --- ## 3. 项目边界 ### 本阶段要做 1. 面板化管理订阅源 2. 规则模块化 3. 规则组合关系数据库化 4. 支持多个输出 Profile 5. 服务端拼装生成完整 YAML 6. 做缓存和快照 7. 支持预览和下载 ### 本阶段不做 1. 不强制对外输出 provider 模式 2. 不做“在线全文编辑 ACL4SSR 大规则文件”为主交互方式 3. 不做复杂多用户权限系统 4. 不做重型前后端分离 5. 不把所有规则全文放 SQLite 6. 不引入 Mongo 做主存储 --- ## 4. 架构原则 ### 原则 1:外部简单,内部灵活 客户端只拿一个完整 YAML。 服务端内部怎么拆、怎么缓存、怎么组合,都由 sub-provider 负责。 ### 原则 2:规则内容文件化,组合关系数据库化 规则正文属于“资产”,继续放文件。 面板管理的是“配置和组合关系”,放 SQLite。 ### 原则 3:90% 的配置修改通过“选模块 + 改参数”完成 不要把面板做成“大文本框配置编辑器”。 ### 原则 4:优先可维护,而不是一开始就追求炫技 先把结构跑顺,再考虑高级模式。 --- ## 5. 总体架构 ```text 输入源 -> 拉取缓存 -> 原始内容缓存 -> 解析节点 -> 节点标准化 -> 节点处理(过滤/去重/重命名/分类) -> 策略组生成 -> 规则模块加载 -> 规则模块参数渲染 -> 规则按顺序拼接 -> 插入 prepend/append 自定义规则 -> 渲染完整 YAML -> 结果缓存 / 生成快照 -> 提供下载 / 预览 / HEAD 信息 ``` --- ## 6. 推荐技术栈 ### 后端 * FastAPI ### 数据库 * SQLite(默认) * SQLAlchemy ORM * Alembic migration ### 模板 * Jinja2 ### 前端 * 优先服务端渲染 * 可用 Jinja2 + HTMX 或简单模板页 * 先不要求 React/Vue 前后端分离 ### 缓存 * 轻量场景下可先用: * SQLite 表 * 本地文件缓存 * 不必一上来引入 Redis --- ## 7. 目录结构建议 ```text app/ api/ routes_sources.py routes_profiles.py routes_rules.py routes_preview.py core/ config.py database.py cache.py db/ base.py session.py models/ source.py profile.py rule_module.py policy_group.py artifact.py schemas/ source.py profile.py rule_module.py services/ source_fetcher.py source_parser.py proxy_normalizer.py proxy_processor.py policy_group_builder.py rule_loader.py rule_renderer.py profile_renderer.py artifact_service.py templates/ base.html sources.html profiles.html rules.html preview.html main.py rules/ modules/ lan.list private.list cn_domain.list cn_ip.list apple.list microsoft.list github.list telegram.list openai.list streaming.list ads.list final_proxy.list final_direct.list presets/ minimal.yaml daily.yaml router.yaml group_templates/ basic.yaml ai.yaml streaming.yaml data/ app.db cache/ raw_sources/ parsed_sources/ generated/ artifacts/ migrations/ tests/ ``` --- ## 8. 规则系统设计 ## 8.1 规则正文:继续放文件 规则正文文件继续按 ACL4SSR 风格维护。 例如: * `rules/modules/apple.list` * `rules/modules/openai.list` * `rules/modules/telegram.list` * `rules/modules/cn_domain.list` * `rules/modules/final_proxy.list` ### 推荐格式 规则文件使用模板变量,不直接写死策略组: ```text DOMAIN-SUFFIX,openai.com,{{ target_group }} DOMAIN-SUFFIX,chatgpt.com,{{ target_group }} DOMAIN-SUFFIX,oaistatic.com,{{ target_group }} DOMAIN-SUFFIX,auth0.openai.com,{{ target_group }} ``` 这样同一个规则模块可复用到不同策略组。 --- ## 8.2 规则模块:放 SQLite SQLite 里存规则模块元数据,而不是规则全文。 ### 表:`rule_modules` 字段建议: * `id` * `key` * `name` * `description` * `file_path` * `category` * `default_enabled` * `default_order` * `default_target_policy` * `params_schema_json` * `created_at` * `updated_at` ### 示例 ```json { "key": "openai", "name": "OpenAI", "file_path": "rules/modules/openai.list", "category": "service", "default_enabled": true, "default_order": 80, "default_target_policy": "🤖 AI", "params_schema_json": { "target_group": { "type": "string", "default": "🤖 AI" } } } ``` --- ## 8.3 Profile 中的规则组合:放 SQLite ### 表:`profile_rule_modules` 字段建议: * `id` * `profile_id` * `module_id` * `enabled` * `order_index` * `target_policy` * `params_json` 含义: * 这个 profile 是否启用这个模块 * 顺序是什么 * 最终绑定到哪个策略组 * 参数是什么 --- ## 8.4 规则预设 可选支持“预设”。 例如: * `minimal` * `daily` * `router` 但预设只作为**初始化模板**,最终仍落到具体 profile 配置里。 不要求上线初期就把预设做得很复杂。 --- ## 9. 策略组系统设计 策略组不要硬编码死在一个大 YAML 模板里。 也要做成可配置对象。 ### 表:`policy_groups` 字段建议: * `id` * `profile_id` * `name` * `type` * `order_index` * `config_json` ### `config_json` 示例 ```json { "proxies": ["DIRECT", "REJECT", "香港节点", "日本节点"], "include_all_nodes": false, "filter": "HK|Hong Kong" } ``` ### 支持的策略组类型 * `select` * `url-test` * `fallback` * `load-balance` ### 建议的默认组 * `🚀 节点选择` * `🤖 AI` * `📺 流媒体` * `🍎 苹果服务` * `📲 Telegram` * `🌍 国外网站` * `🇨🇳 国内网站` --- ## 10. 源管理设计 ### 表:`sources` 字段建议: * `id` * `name` * `type` 值可为: * `base64` * `url` * `link` * `static` * `content` * `headers_json` * `enabled` * `priority` * `update_interval_sec` * `rename_rules_json` * `filter_rules_json` * `dedupe_policy` * `last_sync_at` * `last_sync_status` * `last_error` * `created_at` * `updated_at` ### 说明 这里的源是原始输入源,不是给客户端的 provider。 --- ## 11. Profile 设计 Profile 是最终对外输出的配置单元。 例如: * iPhone 配置 * Windows 配置 * OpenWrt 配置 * Apple TV 配置 * 精简版配置 * 完整版配置 ### 表:`profiles` 字段建议: * `id` * `name` * `description` * `source_ids_json` * `dns_template` * `tun_enabled` * `udp_enabled` * `append_subscription_info` * `expose_head_info` * `enabled` * `created_at` * `updated_at` --- ## 12. 自定义覆盖设计 为了兼容高级用户需求,支持少量覆盖,但不做全文编辑器。 ### 表:`profile_overrides` 字段建议: * `id` * `profile_id` * `custom_rules_prepend` * `custom_rules_append` * `custom_proxy_groups` * `custom_dns_patch` * `custom_yaml_patch` ### 原则 只提供: * prepend rules * append rules * 少量 patch 不鼓励直接在面板里手写全部 YAML。 --- ## 13. 缓存设计 ## 13.1 原始源缓存 缓存拉回来的原始内容。 目的: * 避免频繁请求订阅源 * 降低上游压力 * 出问题可复现 --- ## 13.2 解析结果缓存 把原始内容解析为统一节点模型后缓存。 目的: * 多 profile 复用解析结果 * 避免重复解析 --- ## 13.3 最终 YAML 缓存 同一个 profile 在以下内容不变时,直接返回缓存: * 订阅源内容未变 * profile 配置未变 * 规则模块未变 * 策略组未变 缓存键建议基于 hash: * 源快照 hash * 规则快照 hash * profile 配置 hash --- ## 14. 生成快照设计 ### 表:`generated_artifacts` 字段建议: * `id` * `profile_id` * `version` * `content` * `content_hash` * `source_snapshot_json` * `rule_snapshot_json` * `generated_at` ### 用途 * 预览 * diff * 回滚 * 调试 * 追踪“为什么这次生成结果变了” --- ## 15. 内部统一节点模型 建议在解析层统一成一个内部对象。 ### Python 草案 ```python from pydantic import BaseModel from typing import Any class ProxyNode(BaseModel): name: str type: str server: str port: int udp: bool = True tags: list[str] = [] raw: dict[str, Any] = {} ``` 对不同类型协议(ss、vmess、vless、trojan、hysteria 等)额外字段可放在 `raw` 里。 --- ## 16. 生成流水线 ## 第 1 步:拉取源 * 读取启用的 sources * 获取原始订阅内容 * 更新缓存 * 记录同步状态 ## 第 2 步:解析源 * 解析 base64 * 解析单链接 * 解析远程订阅 * 标准化成统一节点模型 ## 第 3 步:节点处理 * 去重 * 重命名 * 按国家/协议/标签分类 * 过滤无效节点 * 应用 profile 的筛选逻辑 ## 第 4 步:生成策略组 * 读取 profile 绑定的 policy groups * 根据节点分类与过滤规则生成 `proxy-groups` ## 第 5 步:加载规则模块 * 读取 profile 启用的规则模块 * 按顺序加载规则文件 * 渲染模板变量(如 `target_group`) ## 第 6 步:组装规则 * 拼接所有规则模块 * 插入 prepend rules * 插入 append rules * 保证 `MATCH` 规则最后输出 ## 第 7 步:生成完整 YAML 输出包含: * mixed-port / socks-port / redir-port / tproxy-port(按需) * mode * log-level * dns * tun * proxies * proxy-groups * rules ## 第 8 步:缓存与快照 * 计算 hash * 命中缓存则复用 * 否则生成新 artifact --- ## 17. 输出设计 ### 对外输出接口 * `/profiles/{id}/clash.yaml` * `/profiles/{id}/download` * `/profiles/{id}/preview` * `/profiles/{id}/head` ### 输出原则 * 默认返回完整 YAML * 对客户端透明 * 客户端无需理解内部模块化结构 ### 可选响应头 支持将源站订阅信息透传到最终响应头,例如: * `subscription-userinfo` * 其他流量额度相关头 如果多个源混合: * 默认只透传第一个主源的额度信息 * 或后续设计聚合策略,但不是当前必做 --- ## 18. API 草案 ## 源管理 * `GET /api/sources` * `POST /api/sources` * `PUT /api/sources/{id}` * `DELETE /api/sources/{id}` * `POST /api/sources/{id}/test` * `POST /api/sources/{id}/sync` ## 规则模块 * `GET /api/rule-modules` * `GET /api/rule-modules/{id}` * `PUT /api/rule-modules/{id}` ## Profile * `GET /api/profiles` * `POST /api/profiles` * `PUT /api/profiles/{id}` * `DELETE /api/profiles/{id}` ## Profile 规则配置 * `GET /api/profiles/{id}/rules` * `PUT /api/profiles/{id}/rules` ## Profile 策略组配置 * `GET /api/profiles/{id}/policy-groups` * `PUT /api/profiles/{id}/policy-groups` ## 预览与生成 * `POST /api/profiles/{id}/preview` * `POST /api/profiles/{id}/generate` * `GET /api/profiles/{id}/artifacts` * `GET /api/artifacts/{id}` --- ## 19. 面板设计原则 ### 普通模式 允许: * 配源 * 选 profile * 勾选规则模块 * 选择规则模块绑定的策略组 * 调模块顺序 * 加 prepend / append 规则 * 预览生成结果 ### 高级模式 允许: * 编辑少量覆盖配置 * 自定义组模板 * 导入自定义规则模块 ### 不建议 * 直接在线编辑整份 ACL4SSR 规则大文件作为主要操作方式 --- ## 20. 示例规则模块 ## `rules/modules/openai.list` ```text DOMAIN-SUFFIX,openai.com,{{ target_group }} DOMAIN-SUFFIX,chatgpt.com,{{ target_group }} DOMAIN-SUFFIX,oaistatic.com,{{ target_group }} DOMAIN-SUFFIX,auth0.openai.com,{{ target_group }} ``` ## `rules/modules/apple.list` ```text DOMAIN-SUFFIX,apple.com,{{ target_group }} DOMAIN-SUFFIX,icloud.com,{{ target_group }} DOMAIN-SUFFIX,itunes.apple.com,{{ target_group }} DOMAIN-SUFFIX,apps.apple.com,{{ target_group }} ``` --- ## 21. 示例最终输出 YAML 骨架 ```yaml mixed-port: 7890 allow-lan: true mode: rule log-level: info dns: enable: true ipv6: false nameserver: - 223.5.5.5 - 119.29.29.29 proxies: - name: 香港节点 01 type: ss server: 1.2.3.4 port: 443 cipher: aes-128-gcm password: xxxx proxy-groups: - name: 🚀 节点选择 type: select proxies: - 香港节点 01 - 日本节点 01 - DIRECT - name: 🤖 AI type: select proxies: - 🚀 节点选择 - 香港节点 01 - 日本节点 01 rules: - DOMAIN-SUFFIX,openai.com,🤖 AI - DOMAIN-SUFFIX,chatgpt.com,🤖 AI - DOMAIN-SUFFIX,apple.com,🍎 苹果服务 - GEOIP,CN,DIRECT - MATCH,🚀 节点选择 ``` --- ## 22. 数据库配置要求 ### 默认 ```env DATABASE_URL=sqlite:///./data/app.db ``` ### 未来切 PostgreSQL ```env DATABASE_URL=postgresql+psycopg://user:pass@postgres:5432/subprovider ``` ### 要求 * 所有数据库访问都走 SQLAlchemy * migration 走 Alembic * 不写死 SQLite 特性到业务逻辑中 --- ## 23. 开发阶段建议 ## 第一阶段:解耦与最小可用 目标: * 先跑通结构 任务: 1. 引入 SQLAlchemy + Alembic 2. 建 sources / profiles / rule_modules / profile_rule_modules / policy_groups / artifacts 表 3. 将现有规则整理为 `rules/modules/*.list` 4. 将现有单体生成逻辑拆成 service 5. 支持生成一个完整 YAML 6. 提供最简预览页面 --- ## 第二阶段:面板化 目标: * 基础可用 任务: 1. 源管理页面 2. Profile 管理页面 3. 规则模块勾选和排序页面 4. 策略组配置页面 5. 预览和下载页面 --- ## 第三阶段:增强能力 目标: * 更稳定、更可追踪 任务: 1. 快照与 diff 2. 生成缓存优化 3. 同步日志和错误展示 4. 自定义规则导入 5. 自定义组模板 --- ## 24. 明确不推荐的方向 1. 不推荐把 ACL4SSR 规则逐条入 SQLite 2. 不推荐面板主交互是“编辑一万条规则文本” 3. 不推荐一开始就做 rule-provider / proxy-provider 对外发布 4. 不推荐 Mongo 作为主配置库 5. 不推荐先做复杂权限系统 6. 不推荐先做重前端再补业务逻辑 --- ## 25. 给 Codex 的明确执行要求 请按以下要求重构项目: 1. 保留对外输出为单个完整 YAML 2. 将内部生成逻辑改为模块化流水线 3. 规则正文继续使用文件存储 4. 使用 SQLite 存储: * 源配置 * profile 配置 * 规则模块元数据 * profile 与规则模块的绑定关系 * 策略组配置 * 生成快照 5. 使用 SQLAlchemy + Alembic,数据库 URL 可配置 6. 代码结构按 service 分层,避免单文件堆逻辑 7. 首先实现最小可运行版本: * 能配置 source * 能配置 profile * 能选择规则模块 * 能选择目标策略组 * 能生成并预览完整 YAML 8. 不要实现对外 provider 模式作为默认路线 9. 不要将规则正文全文入库 10. 不要将面板设计成规则全文编辑器 --- ## 26. 最终一句话总结 本项目的最终路线是: > **内部模块化、缓存化、可配置化** > **对外输出完整单文件 YAML** > **规则正文继续文件维护** > **规则组合关系和面板配置放 SQLite** 这条路线最符合当前项目阶段,也最稳。 --- 如果你要,我下一条可以继续给你一份**更像任务单的 Codex 执行拆分版**,我会按“先改哪些文件、再改哪些文件、每步验收什么”来写。