项目:X-Pan | 版本:v1.1 | 生成日期:2026-10-06 | 依据:源码分析
本文汇总散落在前七篇(00-06)与本套新篇(07-12)中标注的全部 ⚠️ 待确认项与已知欠账,逐条给出位置/证据/影响/建议,再合并出一份带优先级的演进路线图。口径说明:CODE_AUDIT_2026-09-06.md 所列约 90 项问题已全部修复(含死代码清理,已逐项核实),本文只收"修复后仍存在"的债务——即有意保留的设计取舍、预留未实现的特性、文档漂移与测试缺口;修复史本身不重复展开(索引见《08-安全与权限设计》第 7-8 节)。
D1 离线下载 BT/磁力未实现(protocol 字段仅预留)
x-pan-parent/server/src/main/java/com/xiaoye/pan/server/modules/offline/service/impl/OfflineTaskServiceImpl.java parseProtocol(识别 MAGNET/THUNDER/BT)与 validateUrl(仅放行 http/https);distribution/conf/db.sql x_pan_offline_task.protocol 字段。parseProtocol 会把 magnet 链接标为 MAGNET,但 ALLOWED_PROTOCOLS = Set.of("http","https") 直接拒绝——字段与识别逻辑先行,下载器未落地。parseProtocol 的 BT/MAGNET/THUNDER 分支删掉或注释注明预留语义,避免读码者误解;若要实现,BT 下载器需进独立线程池(复用 pan.offline.thread-pool-size 的隔离模式)并补充种子文件 SSRF 评估(tracker 与 peer 均为任意地址,现有 URL 校验模型不适用)。D2 设备地理位置(device.location)无实际写入
modules/device/service/impl/DeviceServiceImpl.java:87(device.setLocation(""); // 预留,需 IP 库支持)、modules/device/entity/XPanDevice.java:50。db.sql 去字段需走增量脚本规范,参考 server/src/main/resources/sql/ 的追加式迁移)。⚠️ 待确认:产品层面是否需要此能力。D3 WebDAV 能力边界比"协议子集"更窄:实际可用仅 GET/HEAD/DELETE
modules/webdav/WebDavController.java:67-73(@RequestMapping 仅注册 GET/POST/PUT/DELETE/OPTIONS/HEAD 六个方法——PROPFIND/MKCOL/MOVE/COPY 到不了处理器,Spring 路由层即 405)、:254-265(handlePut 返回 501 + "PUT 暂未实现,请使用 Web 端上传")、:282-290(handleMkcol 501)、:351-356(handleMoveOrCopy 501)、:292-339(handlePropfind 桩实现:仅回显请求路径自身元数据,不遍历真实文件树)。deploy/WEBDAV.md 与本文档明示"实际可用面:GET/HEAD/DELETE + OPTIONS 能力探测";中期补齐分两步——先把缺失方法注册进 @RequestMapping 并补"层级路径 → 文件树"解析层,再实现 PUT(复用 IUserFileService.upload,MultipartFile 适配参照离线下载的 TempFileMultipartFile 模式),注意大文件走分片协议或直传的限制(spring.servlet.multipart 3GB 上限)。D4 通知中心无清理策略
modules/notification/(无清理任务);x_pan_notification 表无 TTL 机制;《04-数据模型》8 已标注。idx_user_time 列表查询变慢。D5 OSS/FastDFS 引擎待接线
x-pan-parent/server/pom.xml(两段依赖注释)、application.yaml 尾部注释模板、framework/storage-engine/storage-engine-oss|fastdfs/(代码完整)。common/migration/StorageMigrationRunner.java ⚠️ 待确认完成度,启用前必须实测)。D6 CI docker 发布 job 未接 test 门禁
x-pan-parent/.github/workflows/ci.yml——docker job needs: [backend],文件头注释自述"测试链路刚接入尚未稳定,待连续绿后改为 needs: [backend, test]"。latest tag 拉到生产。needs: [backend, test](一行改动);收紧前可用 GitHub branch protection 把 test 设为 PR 必检,先行拦截合入侧。D7 移动端无 CI、前端无运行时单测
x-pan-mobile/.github/ 无生效 workflow(CHANGELOG.md 有"摘除测试豁免"意图记录);x-pan-fronted/package.json 无测试框架。flutter analyze + flutter test);前端引入 vitest 优先覆盖《09-测试与质量保障》第 6 节列出的四个纯逻辑点。D8 README 用例数漂移(68 vs 源码 53+17)
README.md:7,211 与 x-pan-parent/README.md("68 用例全绿");当前源码 server 53 个 @Test + framework 17 个 = 70;CHANGELOG.md 记录门禁接入时点"68/68 全绿"。mvn test 输出为准"的口径说明;每次增删测试顺手同步。D9 README 默认账号与 db.sql 不符
x-pan-parent/README.md:186("默认账号 admin/admin(请上线前修改)");distribution/conf/db.sql 为纯 DDL 无账号数据;《00-项目总览》5.5 已标注 ⚠️。/user/register 注册(限流 3 次/小时)",或提供 INSERT 示例脚本(PBKDF2 口令需用 PasswordUtil 生成,不能手写明文)。D10 x_pan_recycle_policy 策略表与硬编码 30 天的联动不明
distribution/conf/db.sql x_pan_recycle_policy(policy_type 按时间/按容量、retain_days 默认 30、capacity_ratio 默认 0.90);common/schedule/task/CleanExpireRecycleFileTask.java 按 30 天清理。CleanExpireRecycleFileTask 读策略表(retain_days 生效是低成本改动,capacity_ratio 需要配额联动放后);或删表并在文档说明规划。⚠️ 待确认产品意图。D11 StorageMigrationRunner 完成度未知
common/migration/StorageMigrationRunner.java;仓库无使用文档,00-06 篇亦未覆盖其细节。deploy/ 文档;不可用则标记 @Disabled 并在 SOP-5 标注"迁移需自研脚本"。D12 三处 JVM 锁 + WebDAV AUTH_CACHE 不可水平扩展
CommonLoginAspect.RENEW_KEY_LOCKS、FilePhysicalDeleteEventListener.SEC_UPLOAD_IDENTIFIER_LOCKS、FileChunkServiceImpl.LOCK_MAP、WebDavController.AUTH_CACHE。ConcurrentHashMap 实现的多处锁表与缓存;《04-数据模型》第 7 节已点名前两者。SET NX PX 分布式锁即可,粒度沿用现有业务键);限流器与登录态已是 Redis 共享无需动。顺序上放在"第二实例上线"这个里程碑的前置清单里(见第 3 节路线图)。D13 findAllFileRecords 全量加载(TODO B11)
modules/file/service/impl/UserFileServiceImpl.java:632 TODO 注释;审计"未修事项"声明"改动风险高,保留并加 TODO,建议配合 P5 阶段集成测试重构"。D14 CORS 未配置白名单时回退 *
framework/web/.../cors/CorsFilter.java(空白名单 → Access-Control-Allow-Origin: * + warn 一次)。* 便利——一处 profile 判断即可。D15 run-local.sh 明文密钥落盘 + git 历史含旧密码
x-pan-parent/run-local.sh(7 个真实密钥明文,gitignore 已确认);DEV_GUIDELINES.md 第一节记录的 git 历史扫描结论(仅 x-pan-parent 37 个提交含 4 个真实密码)。.env(deploy 已有该模式)或系统 keychain,run-local.sh 改为加载器;开源/展示前必须先完成历史清洗(filter-repo)+ 全量轮换。D16 移动端 shareToken 存储隔离待复核
x-pan-mobile/lib/core/storage/token_storage.dart(预留 share_token 键);CODE_AUDIT 移动 🟠#11 记录"shareToken 全局单槽永不清理"。ShareIdUtil 与分享归属校验会兜底拒绝,实际风险为体验问题而非越权)。share_detail_page.dart 与 token_storage.dart,按 shareId 隔离存储并在登出/离开分享页时清理。D17 RocketMQ 依赖声明无使用点
x-pan-parent/pom.xml dependencyManagement(rocketmq-spring-boot-starter 2.3.6);全仓库无 Java/配置引用(《00-项目总览》3.1 节核实)。死代码清理已完成的核实结果(写下来避免后人重复排查):CODE_AUDIT 前端 🟡#28 点名的 SortDialog.vue、BaseAutocomplete.vue、useWebSocketAuto 已不存在于 x-pan-fronted/src/;后端 media 空壳模块(10 个 0 字节文件)与 @LoginIgnore test 演示端点已删(CHANGELOG.md chore 段记录)。仍活着的漂移即 D8/D9 两条。另有三处文档互证点已在前篇标注不赘述:《05-核心流程》失败语义表(v1.0)与本套 12 篇 FAQ 的错误文案一致;deploy/WEBDAV.md 的客户端兼容性说明未逐条实测(⚠️ 待确认,使用前以 D3 与《16-决策记录ADR》ADR-010 的能力边界现状为准)。
| 优先级 | 条目 | 一句话理由 |
|---|---|---|
| 立即(一次提交内) | D6(CI 门禁收紧)、D8/D9(README 修正)、D17(删 RocketMQ) | 成本极低、消除误导、闭环门禁 |
| 短期(一个迭代) | D14(CORS prod fail-fast)、D16(复核 shareToken)、D4(通知清理)、D15(密钥迁 .env) | 安全面收敛 + 低成本 hygiene |
| 中期(专项) | D3(WebDAV PUT)、D10(回收站策略生效)、D11(迁移器验证)、D7(移动端 CI/前端 vitest) | 各为一个独立小专项,互不阻塞 |
| 与规模化绑定 | D12(分布式锁)、D13(B11+ref_count) | 单实例下无收益,扩容前必须完成 |
| 按需/产品决策 | D1(BT)、D2(location)、D5(OSS/FastDFS) | 先问"要不要",再谈"怎么做" |
路线图与 README 既有阶段(P5 测试门禁 🚧、P5.5 数据可靠性专项 📋)的衔接:第一阶段即 P5 的收尾(门禁拦截价值闭环);第三阶段整体对应 P5.5(配额原子化、ref_count、备份策略属同一数据可靠性主题);第二、四阶段为能力型演进,可与前两者并行排期。每个阶段动工前,先跑《09-测试与质量保障》第 5 节的完整回归序列——本套文档反复强调的那个判断依然成立:这个代码库最值钱的资产是"约束即文档"的纪律(DEV_GUIDELINES 每条红线都对应一次真实事故),演进时先保纪律再保速度。