# P10-NS4-04：操作日志/审计日志的查看界面

## 简要结论
- 状态：❌ 未解决
- 项目当前没有业务操作审计日志的数据库表、后端记录逻辑、以及前端查看界面。仅有 Excel 上传记录（`biz.excel_upload_log`）和 ETL 任务执行日志（admin-web LogViewer），均不属于业务操作审计日志范畴。

## 详细审查

### 数据库端

**查库方式**：pg-app-test MCP 连接不可用，改用 DDL 迁移文件搜索。

| 检查项 | 结果 |
|--------|------|
| `audit_log` / `operation_log` / `activity_log` 表 | ❌ 不存在（DDL 搜索无匹配） |
| `auth` schema 中日志相关表 | ❌ 不存在（仅有 `users`、`tenant_admins`、`user_roles`、`user_site_roles`、`user_applications`、`user_assistant_binding`） |
| `biz` schema 中日志相关表 | ⚠️ 仅有 `biz.excel_upload_log`（Excel 上传批次记录，非操作审计日志） |
| `task_execution_log` 表 | 存在于 `_archived/` 基线中，属于 ETL 任务执行日志，非业务操作审计 |

**结论**：数据库中不存在通用的业务操作审计日志表。`biz.excel_upload_log` 记录的是 Excel 上传批次状态（pending/confirmed/failed），不记录"谁做了什么操作"这类审计信息。

### 后端代码

| 检查项 | 结果 |
|--------|------|
| `apps/backend/app/routers/` 中审计日志路由 | ❌ 不存在（无 `audit`/`log`/`activity` 相关路由文件） |
| 审计中间件 / 日志记录装饰器 | ❌ 不存在（`app/middleware/` 仅有 `response_wrapper.py` 和 `permission.py`） |
| `tenant_users.py` 审核操作日志 | ❌ 审核通过/拒绝仅更新状态字段（`user_applications.status`、`reviewed_by`、`reviewed_at`），不写入独立审计日志表 |
| `tenant_clues.py` 线索操作日志 | ❌ 编辑/删除/隐藏操作直接修改数据，无审计记录 |
| `tenant_excel.py` 上传操作日志 | ⚠️ 写入 `biz.excel_upload_log`，但仅记录批次元数据，不记录操作人的具体行为 |

**关键发现**：
- 用户审核（通过/拒绝）：`user_applications` 表有 `reviewed_by` + `reviewed_at` 字段，可追溯审核人和时间，但不是独立的审计日志
- 用户编辑（状态变更/绑定修改）：无任何操作记录
- 维客线索修改/删除/隐藏：无任何操作记录，且删除为物理删除（`DELETE FROM`），数据不可恢复
- Excel 上传：`excel_upload_log` 记录了 `uploaded_by`，但无确认操作的审计

### 前端代码

| 检查项 | 结果 |
|--------|------|
| `apps/tenant-admin/src/pages/` 中日志查看页面 | ❌ 不存在（仅有 Login、UserApproval、UserManagement、ExcelUpload、RetentionClues 五个页面） |
| `apps/tenant-admin/src/App.tsx` 路由配置 | ❌ 无日志相关路由（路由：`/login`、`/applications`、`/users`、`/excel`、`/clues`） |
| `apps/admin-web/src/pages/LogViewer.tsx` | ⚠️ 存在，但功能是 ETL 任务执行日志查看器（通过 WebSocket 接收执行日志、按任务分组展示），不是业务操作审计日志 |
| `apps/admin-web/src/App.tsx` 路由 `/log-viewer` | 指向 ETL LogViewer，与业务操作审计无关 |

**结论**：两个前端应用均无业务操作审计日志查看界面。

### 差距分析

P10 标杆文件要求管理后台具备操作审计功能，即"谁在什么时间做了什么操作"的完整追溯能力。当前 NS4 的差距：

| 维度 | P10 要求 | NS4 现状 | 差距 |
|------|----------|----------|------|
| 审计数据存储 | 独立审计日志表 | ❌ 不存在 | 完全缺失 |
| 审计记录写入 | 关键操作自动记录 | ❌ 无中间件/装饰器 | 完全缺失 |
| 审计日志查看 | 管理后台可查看/筛选 | ❌ 无页面 | 完全缺失 |
| 操作可追溯性 | 所有关键操作可追溯 | ⚠️ 仅审核操作有 `reviewed_by`/`reviewed_at` | 大部分缺失 |
| 数据安全 | 删除操作可恢复/可审计 | ❌ 线索删除为物理删除 | 高风险 |

### 建议

#### 短期（高优先级）

1. **新建审计日志表** `biz.audit_log`：
   - 字段：`id`、`site_id`、`operator_id`（操作人）、`operator_type`（tenant_admin/system）、`action`（approve/reject/edit/delete/hide/upload 等）、`target_type`（user/clue/excel 等）、`target_id`、`detail`（JSONB，变更前后值）、`ip_address`、`created_at`
   - 索引：`(site_id, created_at DESC)`、`(operator_id)`、`(target_type, target_id)`

2. **后端审计中间件/工具函数**：
   - 在 `tenant_users.py` 的审核通过/拒绝、用户编辑/禁用操作中写入审计日志
   - 在 `tenant_clues.py` 的编辑/删除/隐藏操作中写入审计日志
   - 在 `tenant_excel.py` 的上传确认操作中写入审计日志
   - 建议实现为可复用的 `log_audit()` 工具函数，在事务内调用

3. **线索删除改为软删除**：当前 `DELETE FROM public.member_retention_clue` 为物理删除，建议改为 `SET is_deleted = true`，配合审计日志记录

#### 中期

4. **前端审计日志查看页面**（tenant-admin）：
   - 新增 `/audit-logs` 路由和 `AuditLogs` 页面
   - 支持按时间范围、操作类型、操作人筛选
   - 展示操作详情（变更前后对比）

5. **后端审计日志查询 API**：
   - `GET /api/tenant/audit-logs`（分页 + 筛选）
