# RRPP Lite 模块拆分计划 ## 目标与边界 将当前 `main.py`(约 3,480 行)渐进拆成职责清晰、可独立测试的模块,同时保持以下行为不变: - PAC、全局代理、智能分流和本地 TLS 转发的现有接口与优先级; - 节点订阅、DPAPI 加密存储、登录及本地运行数据位置; - 源码运行、PyInstaller 单文件版和 Nuitka 版的启动方式; - 现有 `lite/test/test_pac_routing.py` 的全部回归用例。 本轮拆分期间**不提交、不推送到主仓库、不打包发布**。每个阶段均只在本地工作区验证;出现回归时优先回退到拆分前备份。 ## 开始前的保护措施 1. 记录当前 Git 状态与当前 HEAD,不触碰既有未跟踪的构建产物、备份和用户文件。 2. 在 `lite/backups/` 创建带时间戳的源码备份,例如: `proxy_lite.py.bak_YYYYMMDD_HHMMSS_before_module_split`。 3. 首次拆分前运行一次完整基线: ```powershell wsl.exe -e bash -lc "cd '/mnt/d/Royirin Rosmontis Private Proxy' && python3 -m py_compile lite/main.py lite/test/test_pac_routing.py && python3 lite/test/test_pac_routing.py" ``` 4. 每完成一个阶段,先做编译检查,再跑完整 PAC 回归;不通过则在进入下一阶段前修复或回退。 ## 当前实施进度(2026-09-16) - [x] 已创建拆分前备份:`lite/backups/proxy_lite.py.bak_20260916_220240_before_module_split`。 - [x] 已完成一次拆分前基线与多次拆分后全量 PAC 回归。 - [x] UI 主题、控件和三个对话框已迁入 `rrpp_ui/theme.py`、`rrpp_ui/widgets.py`、 `rrpp_ui/dialogs.py`;通过显式服务对象调用业务层,不反向导入入口文件。 - [x] 已迁入核心包的无状态功能:CIDR/Trie 与 PAC 规则解析、PAC 拉取和原子写入、 `settings.json` 原子存储、DPAPI 节点/凭据存储、HTTP 转发报文解析与认证注入、 DNS/私网判断与 TTL 缓存、流量统计、节点认证请求协议。 - [ ] 节点同步服务、带缓存的完整路由决策、转发器 socket 生命周期、系统代理注册表控制 和主窗口仍在入口文件,待后续阶段继续迁移。 - [x] 已获得用户授权,在完成构建与验证后执行 `git commit`、`git push` 和 Release 发布。 ## 目标目录 ```text lite/ ├─ main.py # 轻量入口、组装依赖、main ├─ rrpp_core/ │ ├─ __init__.py │ ├─ runtime.py # 路径、常量、日志与共享运行时上下文 │ ├─ config_store.py # 普通配置、节点、DPAPI 凭据 │ ├─ pac_data.py # PAC 在线数据下载、校验、缓存失效 │ ├─ routing.py # 域名/IP 分流、白名单、CIDR/Trie │ ├─ forwarder.py # 本地 TLS 转发、HTTP CONNECT、认证注入 │ └─ system_proxy.py # PAC 服务、Windows 系统代理状态 ├─ rrpp_ui/ │ ├─ __init__.py │ ├─ theme.py # UI 色彩与样式常量 │ ├─ widgets.py # NodeLabel、开关、状态点等可复用控件 │ └─ dialogs.py # 登录、白名单、设置对话框 └─ test/ └─ test_pac_routing.py ``` 目录是目标形态,而不是一次性迁移要求。入口已统一为 `main.py`;测试和构建脚本均以该文件为准。 ## 分阶段实施 ### 阶段 0:基线与备份 - 创建源码备份并保存当前测试输出。 - 核验当前核心测试:PAC 规则优先级、IPv4/IPv6、私网、CONNECT 解析、认证注入、启动连通性校验及其取消流程。 - 产物:可随时恢复的单文件版本;无业务代码变更。 ### 阶段 1:抽取无状态 UI 组件 - 将 `NodeLabel`、`ToggleSwitch`、`StatusDot` 及图标辅助逻辑移到 `rrpp_ui/widgets.py`。 - 主窗口继续从原入口导入/调用,保持控件信号、样式和构造参数不变。 - 风险低:不涉及代理线程、注册表或路由决策。 - 验收:`py_compile`、PAC 全量测试、一次 Windows GUI 手工启动。 ### 阶段 2:建立共享运行时与配置存储 - 抽取路径常量、配置读写、节点读写、DPAPI 加解密、认证保存和订阅节点同步至 `rrpp_core/runtime.py`、`config_store.py`。 - 明确依赖方向:模块不得反向导入 UI;日志通过注入函数或统一运行时上下文提供。 - 保持 `%LOCALAPPDATA%\\RRPP`、配置文件名、加密格式和节点选择恢复逻辑完全兼容。 - 风险中等:涉及用户已有数据;只做机械迁移,不改变存储格式。 - 验收:现有节点可读取;登录/同步至少做一次人工冒烟;全部自动测试通过。 ### 阶段 3:抽取 PAC 数据与路由引擎 - 将 PAC 数据下载/校验/写入和缓存失效移至 `rrpp_core/pac_data.py`。 - 将白名单、强制代理、明确直连域名、CIDR、IPv6、DNS 解析、Trie 匹配和直连决策移至 `rrpp_core/routing.py`。 - 使用显式的 `RoutingContext` 或等价配置对象替代跨模块全局变量;规则优先级必须锁定为: ```text 用户白名单 > 强制代理 > 明确直连域名 > LAN/私网 > GeoIP 智能分流 ``` - 风险最高的核心阶段;禁止顺便修改规则语义或远程 PAC 格式。 - 验收:扩充并运行分流回归测试,覆盖 Google/OpenAI/Anthropic、国内直连、IPv6、无 DNS 结果与缓存刷新。 ### 阶段 4:抽取转发器与系统代理控制 - 将流量统计、本地 TLS 监听、CONNECT/绝对 URL 解析、认证注入与连接回退移至 `rrpp_core/forwarder.py`。 - 将 PAC HTTP 服务、注册表备份/恢复、全局/PAC 开关和陈旧状态清理移至 `rrpp_core/system_proxy.py`。 - 以明确的 start/stop 生命周期对象管理线程与端口,避免模块级状态互相覆盖。 - 风险中高:涉及注册表和后台线程;本阶段不改变任何系统代理策略。 - 验收:本地端口监听、PAC 开关、全局开关、取消启动、退出清理和重复启停的人工测试;完整回归测试。 ### 阶段 5:抽取对话框与收敛入口 - 将 `LoginDialog`、`WhitelistDialog`、`SettingsDialog` 移至 `rrpp_ui/dialogs.py`,`MainWindow` 可保留在入口或迁到 `rrpp_ui/main_window.py`。 - `main.py` 收敛为:初始化 DPI/单实例、创建运行时、装配 UI、调用 `main()`。 - 保留必要的兼容导出,待构建脚本和测试完全迁移后再移除。 - 验收:源码 GUI 手工走查、全量自动测试、PyInstaller/Nuitka 各做一次仅本地的构建与启动冒烟。 ### 阶段 6:清理与交付前评审 - 删除已确认无引用的兼容层,补齐模块文档和最小单元测试。 - 检查循环导入、隐式全局状态、未关闭线程、路径在冻结环境下的差异。 - 对比拆分前后的 PAC 输出和系统代理状态变更。 - 仅在用户确认后,另行决定提交、推送、打包和发布;它们不属于本次拆分的自动后续动作。 ## 依赖与架构约束 ```text main.py → rrpp_ui → rrpp_core │ │ └───────────┘(仅通过显式上下文/接口协作) ``` - `rrpp_core` 不依赖 PyQt;这样 PAC 与转发逻辑可在无 GUI 环境测试。 - UI 不直接读写注册表、节点文件或 socket;统一通过核心服务对象操作。 - 禁止新的模块级可变全局状态,已有状态在迁移时集中到上下文或生命周期对象。 - 配置、加密和 PAC 文件的文件名、字段、URL 与优先级,在本次重构内视为兼容性契约。 ## 验收清单 - [x] 源码 `py_compile` 通过。 - [x] `test_pac_routing.py` 全部通过。 - [ ] PAC 启动/取消、全局模式、退出恢复系统代理均可用。 - [ ] 既有节点和已加密凭据可读取,订阅同步不回退格式。 - [ ] `chatgpt.com`、`auth.openai.com`、`claude.ai`、Google CDN 仍命中强制代理;国内显式直连规则仍生效。 - [x] PyInstaller 与 Nuitka 均已完成本地构建;Release 附件将使用版本化文件名和 SHA-256 校验。 - [x] 发布暂存仅包含本轮源码、测试、构建脚本、图标和模板;构建产物、账号数据和备份文件已排除。 - [ ] 待提交、推送并上传 Release 附件。 ## 回滚策略 任一阶段出现无法在当前阶段定位的回归时:停止继续迁移,将该阶段涉及文件恢复到阶段开始前的本地备份或 Git 基线;保留失败现场的测试输出以便定位。不得通过覆盖用户的运行配置、订阅或构建目录来“修复”回归。