# 版本管理反模式（2026-07-01 反委托代发工资协议惨痛教训）

## 事件回顾

反委托代发工资协议需要制作两个版本（法定安排 vs 反委托保护），同时保留华诚-Z的修订痕迹。

### 灾难链条

1. 原始文件有华诚-Z的修订（author="华诚-Z"）+ 批注
2. 我制作WB版本时，把所有author改成了WB
3. 又做了一版合并版本，再次覆盖
4. 之后Doro说"你把华诚-Z修订痕迹的版本放进去"
5. 发现/tmp里所有文件都只有WB作为author
6. Nextcloud版本历史也没有（只保留了一个.v文件，也是WB）
7. 最终在 `/tmp/v1_doro_updated.docx` 找到——这是一个中间版本，纯属侥幸

### 反模式清单

| 反模式 | 后果 |
|--------|------|
| 修改author前不备份 | 原始修订痕迹不可逆丢失 |
| 覆盖式保存（同文件名） | 中间版本消失 |
| 从头重做而非增量修补 | 每次重做都覆盖上一版 |
| 不验证就交付 | 批注丢了3条没发现 |
| 多轮操作共用/tmp目录 | 后续操作的文件名与前面冲突 |

### 正确做法

```python
import shutil
from datetime import datetime

# 操作前备份
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
shutil.copy(source, f"{source}.bak_{timestamp}")

# 操作后验证
import zipfile, re
z = zipfile.ZipFile(output)
content = z.read('word/document.xml').decode('utf-8')
authors = set(re.findall(r'w:author="([^"]+)"', content))
assert '华诚-Z' in authors, "华诚-Z author LOST!"

# 批注验证
if 'word/comments.xml' in z.namelist():
    comments_xml = z.read('word/comments.xml').decode('utf-8')
    comment_count = len(re.findall(r'<w:comment ', comments_xml))
    assert comment_count >= expected_count, f"Comments lost: {comment_count} < {expected_count}"
```

### 文件命名规范（防覆盖）

不要用 `_v2.docx` `_v3.docx` 这种递增命名——容易忘记当前版本是几。用语义+时间戳：

```
反委托_华诚Z原版_20260701_0320.docx    # 带华诚-Z修订的版本
反委托_WB合并版_20260701_0341.docx     # WB+华诚-Z合并后
反委托_V1法定安排_FINAL_20260701.docx   # 最终交付
```
