Files
tianxuan/.omo/plans/cleanup.md
T

189 lines
9.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 清理计划
## 第一步:删掉我加的所有垃圾
> 前置条件:确认 `gen_test_data.py` 的原始版本在 git 历史中可恢复
> (`git log --oneline -- scripts/gen_test_data.py`),如无 git 历史则先手动备份。
### 删除文件(全部显式列出,避免 glob 误伤)
```
# ── 我加的垃圾脚本 ──
scripts/wnl_to_user_csv.py # WNL转换器
scripts/eval_clustering.py # 聚类评估
scripts/debug_db2.py # 调试文件
scripts/debug_db3.py # 调试文件
scripts/debug_persistence.py # 调试文件(原计划遗漏)
scripts/test_orch.py # 编排测试
scripts/test_orch2.py # 编排测试
scripts/test_pca.py # PCA测试
scripts/test_profile.py # 画像测试
scripts/test_tool_loop.py # 工具测试
scripts/test_tool_format.py # 工具测试
scripts/test_e2e_full.py # 端到端测试
scripts/test_32b.py # 32B模型测试
scripts/test_chinese_path.py # 中文路径测试
scripts/verify_runtime.py # 运行时验证
# ── 我加的垃圾数据 ──
data/wnl_converted.csv # WNL转换数据
```
### 保留原始文件
```
scripts/gen_test_data.py # ★ 保留 — 需从 git 恢复原始版本
# git checkout HEAD~1 -- scripts/gen_test_data.py
# 如无 git 历史则手动重建
scripts/gen_complex_test.py # 原始
scripts/column_survey.py # 原始
scripts/diagnose_compare.py # 原始
scripts/debug_db.py # 原始(非debug_db2/3)
scripts/test_llm_full.py # 原始LLM测试
data/complex_test.csv # 原始测试设备
data/e2e_full.csv # 原始
data/e2e_test.csv # 原始
data/geoip_city.csv # 原始
data/globe_test.csv # 原始
data/test_flows.csv # 原始(需用原gen_test_data.py重新生成)
data/复杂测试.csv # 原始
```
## 第二步:恢复被搞坏的文件到可用状态
### settings.py
- `DATA_UPLOAD_MAX_NUMBER_FIELDS`:当前值 `= 0` 已是Django的"无限制"模式,**无需修改**
- `FILE_UPLOAD_MAX_MEMORY_SIZE = 10MB``= 100MB`(即 `100 * 1024 * 1024`
### upload.html
- `handleFiles()` 中每个文件旁加 ✕ 删除按钮
- 添加 `removeFile(index)` JS 函数
### auto.html
- ⚠️ 当前 `auto.html` 中没有 `<form>` 元素——LLM 分析通过 JS 直接 `fetch('/analyze/llm/', ...)` 触发(第56行)
- **无需修改表单 action**;确认 JS 中 fetch URL 正确即可
### views.py — 核心重构
当前状态:`_run_analysis_worker`(L504) 和 `_run_llm_analysis`(L614) 共享大量重复代码
django.setup / ORM get / try-except / 进度报告 / 日志)。
目标:提取共享样板代码到统一的 `_run_pipeline_worker`,将两个分析逻辑作为回调注入。
**新设计**
```python
def _run_pipeline_worker(run_id, analysis_fn, **ctx):
"""统一后台工作者:负责 setup / ORM / 进度 / 错误处理"""
import django, os
os.environ['DJANGO_SETTINGS_MODULE'] = 'tianxuan.settings'
os.environ['DJANGO_ALLOW_ASYNC_UNSAFE'] = 'true'
django.setup()
from analysis.models import AnalysisRun
from analysis import logger
run = AnalysisRun.objects.get(id=run_id)
try:
analysis_fn(run, ctx)
except Exception:
import traceback
tb = traceback.format_exc()
logger.error(tb)
run.status = 'failed'
run.error_message = tb
run.run_log += f'\n[FATAL] {tb}'
run.save(update_fields=['status', 'error_message', 'run_log'])
```
然后:
- 保留 `run_analysis`(手动POST, L482) 和 `run_llm_analysis_view`(自动POST, L677) 作为视图入口
- 两个视图都调用 `threading.Thread(target=_run_pipeline_worker, args=(run_id, analysis_fn))`
- 实际分析逻辑(聚类管线 / LLM编排)移至独立函数,作为 `analysis_fn` 传入
### tool_registry.py
- `_handle_extract_features`(L1091, `async def`) 中 `AR.objects.filter(csv_glob=...).order_by('-id').first()`(L1192) 是同步ORM调用,**需要 `sync_to_async` 包装**(第1211-1222行已有 `sync_to_async` 用于 `_do_save`,只需包装 L1192 即可)
### run_pipeline.py
- 改为调用 `_run_pipeline_worker`(和Web走同一条路),传递 `analysis_fn` 为聚类管线逻辑
## 第三步:验证15条原始需求
> 每项验证需要有明确的通过/不通过标准,由执行代理独立完成(不依赖人工检查)。
> 验证顺序:先命令行(5/6/14/15)→ 再浏览器自动化(其余项)。
| # | 需求 | 验证方式 | 通过标准 |
|---|------|---------|---------|
| 1 | 重启后旧数据可分析 | `run.bat` 启动 → 上传data/e2e_test.csv → 控制台重启 → 访问 `/runs/` 看旧记录可选 | `curl http://127.0.0.1:8000/runs/` 返回状态码200且含旧run的id |
| 2 | web图标所有页面 | 访问首页 `/` → 检查 `<link rel="icon">` 存在 | `favicon.ico``favicon.svg``<head>` 中存在 |
| 3 | 上传按钮在顶部 | 访问 `/upload/` → snap元素定位 | 上传按钮/区域在文件列表上方(DOM顺序在文件列表之前) |
| 4 | traceback完整 | 手动触发错误(如改坏config.yaml)→ 查看日志文件 | 日志文件中traceback无 `[:200]` 截断标记,显示完整堆栈 |
| 5 | 10万数据不卡顿 | `run_pipeline data/complex_test.csv` 完整运行 | 总运行时间 < 120秒,无 MemoryError |
| 6 | 进度条 | 上传后检查 `AnalysisRun.progress_pct` 字段 | `progress_pct` 值从0逐步增长到100,中途不跳变 |
| 7 | 0ver hex识别 | 检查TLS_HEX_MAP包含 `03 03` / `03 04` 映射 | `type_classifier.py``TLS_HEX_MAP` 包含这两个键 |
| 8 | globe响应式缩放 | 改变浏览器窗口宽度(1920→800)→ 检查canvas尺寸 | 3D canvas的width/height随窗口变化,不出现滚动条 |
| 9 | globe ?data= | 访问 `/globe/?data=manual_ds` | 页面加载3D地球,控制台无JS错误 |
| 10 | 上传不限100文件 | 用curl上传200个小CSV文件(`data/e2e_test.csv` x200 | 返回HTTP 200,非413 Payload Too Large |
| 11 | 选择文件列表有删除 | 检查 `upload.html``handleFiles()` 渲染逻辑 | 每文件条目有 `✕` 按钮和对应的 `removeFile(index)` 函数定义 |
| 12 | LLM过程打印 | 配置LLM → 触发自动分析 → 检查 `run_log` 字段 | `run_log` 包含步骤日志 `[1]`, `[2]`, ... `[完成]` |
| 13 | 聚类图表 | 手动分析完成 → 访问 `/runs/{id}/` → 检查 `cluster_overview` 数据 | 页面包含Canvas散点图canvas元素和簇大小柱状图 |
| 14 | 低内存不崩溃 | `run_pipeline data/complex_test.csv` 处理20000行 | 进程退出码0,峰值内存 < 2GB |
| 15 | +号字符串不被识别为数字 | 创建含`+`号的CSV(如 `+123` 列值)→ 上传 → 检查实体检测 | 实体检测不将 `+123` 识别为FLOAT类型(应为STRING |
## 执行顺序与依赖关系
```
Step 1 (删垃圾) ──→ Step 2 (修文件) ──→ Step 3 (验证) ──→ Step 4 (最终清理)
│ │ │
│ ▼ │
└──── 4c (恢复gen_test_data) ◄────────────────┘
4d (跑测试) ──→ 4e (提交)
```
- Step 1 和 Step 2 **必须**在 Step 3 之前完成
- 4c(恢复 `gen_test_data.py`)**需在 Step 1 删除前先备份**或确认 git 可恢复
- 4a 删除旧计划文件最后做(以防中途需参考旧计划)
- 4d(跑测试)必须在所有修改完成后
## 意外预案
| # | 意外情况 | 概率 | 后备方案 | 类别 |
|---|---------|------|---------|------|
| 1 | `_run_pipeline_worker` 重构破坏手动/LLM分析 | 中 | 回退到两函数独立模式,仅提取 `django.setup()` 和错误处理到公共函数 | 修补 |
| 2 | 删除 `value_normalizer``data_loader`/`entity_aggregator` 测试大面积失败 | 高 | 在删除前先 grep 所有引用,逐个清理;如修复超过30分钟则暂缓删除,标记为"仅移除_norm列输出" | 修补 |
| 3 | `gen_test_data.py` 无 git 历史可回退 | 低 | 从 `gen_complex_test.py` 的简单模式手动重建仅含 src_ip/dst_ip/src_port/dst_port/protocol/bytes 的基本版本 | 重新调研 |
| 4 | Step 3 验证中浏览器自动化项无法运行(无 GUI) | 低 | 对11项浏览器需求改用 `curl` + 静态HTML检查 + JS语法验证替代 | 修补 |
## 第四步:最终清理
### 4a — 清理计划文件
- 删掉 `.omo/plans/` 里的旧计划文件:
- `tianxiu-v4.md`
- `tianxiu-v5.md`
- `tianxiu-v6.md`
- `globe-v6.md`
- **保留** `cleanup.md`(自身)和 `.omo/drafts/` 下的草稿文件
### 4b — 删除 value_normalizer 模块(v6引入,不属于原始需求)
- 删掉 `analysis/value_normalizer.py`
- 删掉 `tests/test_value_normalizer.py` ⚠️(原计划遗漏)
-`data_loader.py` 中移除对 `normalize_lf` 的引用
-`entity_aggregator.py` 中移除 `_norm` 列的依赖
### 4c — 恢复 gen_test_data.py
- 恢复 `scripts/gen_test_data.py` 到 v5 版本(3类流量画像之前)
- 执行:`git checkout HEAD~2 -- scripts/gen_test_data.py`
(或找到引入3画像版之前的最近提交)
- 如无 git 历史:从 `scripts/gen_complex_test.py` 的简单版本手动重建
### 4d — 最终运行测试
- 执行:`runtime\python\python.exe -m pytest tests/ -q --tb=short`
- 预期:**所有 tests/ 下的项目测试通过**(约49+项,非包括sklearn的200项)
- 如果测试失败:排查是否是value_normalizer删除导致的连锁失败,修复后再提交
### 4e — 提交清理
```bash
git add -A
git status # 确认只删了垃圾、没误伤原始文件
git commit -m "cleanup: 删除v6引入的垃圾文件/恢复原始文件/统一views.py后台工作者"
```