tm-desensitize/PROGRESS-backend.md

48 lines
3.2 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

# tmkit 后端管线 · 进展报告(管线组)
**日期**:2026-11-03 **状态**:✅ 最小可用版交付,pytest 12/12 全绿
## 做了什么
在 `金唐智法/tm/tmkit/` 交付 Python 库 `tmkit`(纯库,不含 Web),四大核心模块 + 测试 + 文档:
| 模块 | 内容 |
|---|---|
| `splitter.py` | PDF 分流:`get_text` 检测文字层,逐页返回 `native` / `scanned`(阈值可调) |
| `extractor.py` | 原生页按词抽取 bbox(`get_text('words')`);扫描页 `raise NotImplementedError('OCR 待接入 PaddleOCR')` |
| `detector.py` | PII 识别引擎:身份证 18 位(GB 11643 校验位验证)、大陆手机号、银行卡(Luhn 校验)、统一社会信用代码(GB 32100 校验)、邮箱;输出 `[{type, text, page, bbox}]`,支持 `register()` 自定义规则 |
| `redactor.py` | 坐标回写:两种方案都实现了——`add_redact_annot + apply_redactions`(默认,真删文字,测试验证 PII 从文本层消失、黑块像素可见)和 `draw_rect` 黑条(对比保留);输出脱敏后 PDF bytes |
| `tests/` | reportlab 动态生成 3 个样例 PDF(纯中文文本页 / 身份证+手机号+银行卡+邮箱页 / 空白扫描页,中文字体用 STSong-Light CID),12 个用例全链路验证 |
| `README.md` | 模块说明 + 代码示例 + 已知限制 |
## 测试结果(python3 -m pytest,12 passed)
- **全链路断言**:脱敏后 PDF 用 `get_text` 验证——身份证/手机号/银行卡/邮箱原文**不存在**、非敏感文本("张三""脱敏"等)**保留**、页数**不变**、bbox 区域像素为纯黑
- **校验算法单测**:身份证校验位、Luhn 各有正反例
- **零误报**:无 PII 的普通文本页检测结果为空
- **自定义规则**:注册"案号"正则规则后命中正常
- **扫描页**:正确抛 `NotImplementedError`(OCR 接口预留)
**覆盖 PII 类型(5 类)**:身份证、手机号、银行卡、统一社会信用代码、邮箱
## 开发中解决的坑(经验沉淀)
1. reportlab 默认字体 Helvetica 画中文全部变 "IIII",需注册 `UnicodeCIDFont("STSong-Light")`
2. Python 正则 `\b` 在"中文紧贴数字"(如 `身份证号110101...`)处不成立(中文和数字都是 Unicode `\w`),已改用 ASCII-only lookaround 边界
3. 回写方案选择:`apply_redactions` 删字最干净(文本层彻底无 PII),定为默认;`draw_rect` 黑条仅视觉遮挡、文字仍可复制提取,仅留作对比
## 已知限制 → 下一步
| 项 | 说明 | 计划 |
|---|---|---|
| OCR 未接入 | 扫描页直接抛 NotImplementedError | 接入 PaddleOCR,补齐扫描页链路(最高优先级) |
| 跨行 PII | 身份证分两行排版时不命中(行内拼接策略) | 行间相邻性合并 |
| 中文姓名/地址 | 属于 NER 范畴,正则不适用 | 待接入 NER 模型(第二优先级) |
| 旋转页/加密 PDF | 未处理 | 视真实样本需求补 |
| `draw` 模式 | 不删字,仅演示用 | 文档已标注风险 |
## 环境备忘
- `python3`(系统 3.9)+ pymupdf 1.26.5 / reportlab 5.0.0 / pytest 8.4.2(pip --user)
- 复跑:`cd 金唐智法/tm && python3 -m pytest tmkit/tests/ -v`