# IT 运营 / AI Coding 工具用量 - 产品需求文档

> **版本**: v0.1
> **状态**: Draft（待 review）
> **创建日期**: 2026-05-15
> **最后更新**: 2026-05-15
> **提单**: [Issue #338](http://43.130.59.228/FFAIWorkspace/workspace/issues/338)
> **负责人**: chentao.jia

---

## ✅ 机器读取区（必填）

### 通用字段

| 字段 | 内容 |
|------|------|
| 模块 | IT 运营 / AI Coding 工具用量（`it-operations/ai-usage`） |
| 文档类型 | PRD |
| 目标 | 为全公司 Claude Code + Codex CLI 用量提供跨员工、跨机器、跨项目的集中可见 dashboard，使管理层能做成本分摊、异常识别和 ROI 度量；员工能看到跨机器累计用量培养成本意识 |
| 范围 | In Scope: 客户端 Node 二进制 agent；员工自助 personal token；服务端 ingestion API；admin 全公司 dashboard；员工自查页；device 列表与拉黑；CSV 导出；1 年热数据 + 永久归档。Out of Scope: 告警/预算阈值；Cursor/Copilot；团队维度权限细化；ROI 度量；HR offboarding 自动撤销 |
| 核心规则 | 只采 token / metadata，永不采消息内容；身份通过 personal token 强约束，零 admin 介入；同一员工多机器共用一个 token；token bcrypt 存储、UI 仅显示 prefix；project 路径完整存储，admin 可见全路径；事件 `rawMessageId` UNIQUE 去重；1 年后归档为日级聚合 + 物理删除 event；所有可见文案双语 |
| 验收标准 | 管理层在 `/it-operations/ai-usage` 30 秒内能说出上月 Top 用量员工/项目/模型；员工在 `/me/ai-usage` 看到跨所有机器累计；员工 `curl install.sh \| bash` + `ffctk login <token>` + `ffctk start` 三步接入；admin 能拉黑陌生 device；csv 导出可给财务 |
| 关联文档 | `02-user-journey.md` / `03-architecture.md` / `04-state-machine.md` / `05-ui-interaction-spec.md` / `06-data-model.md` / `07-api.md` / `08-error-codes.md` / `09-test-scenarios.md` |

### 功能清单（最小）

| 功能 | 优先级 | 说明 |
|------|--------|------|
| 客户端 Node agent | P0 | watch JSONL，增量解析，批量上报，离线缓冲；三平台单 binary |
| Personal token 自助管理 | P0 | 员工在 `/me/ai-usage/tokens` 自助生成 / 命名 / 撤销 |
| Ingestion API | P0 | `POST /api/v1/ai-usage/events` Bearer token 鉴权 + 去重 + device 自动注册 |
| Admin 全公司 dashboard | P0 | 日/周/月用量+成本，按员工/项目/工具/模型下钻，趋势曲线 |
| 员工自查页 | P0 | 跨机器累计 + 项目分布 + 个人 token 管理 |
| Admin device 列表 + 拉黑 | P0 | read-only 列表，应急拉黑 |
| CSV 导出 | P0 | 月度报表导出供财务 |
| JSONL 双 parser（Claude + Codex） | P0 | 插件化字段映射，向后兼容 |
| 数据归档 cron | P0 | 1 年外的 event 月度归档为日级聚合表 + 物理删除原 event |
| Audit log 写入 | P0 | token 生成/撤销、device 拉黑 |
| 告警阈值 | P2 | 第二期 |
| 团队维度权限 | P2 | 第二期 |
| HR offboarding 自动撤销 token | P2 | 第二期 |
| Cursor / Copilot 接入 | P2 | 第二期 |
| ROI 度量 | P3 | 第三期 |

---

## 🧭 人类阅读区（可选）

### 背景

公司全员开始大量使用 AI Coding 工具（Claude Code、Codex CLI），用量分散在多台员工机器、多个项目，管理层完全没有全局视图：

- **不知道钱花在哪**：月度 AI 订阅/API 成本谁占多少、哪个项目最烧——只能看到总账单
- **不知道用得对不对**：员工或项目 quota 飙升时没有任何信号
- **不知道用得值不值**：无法度量 X 模块的 AI 投入 vs 产出
- **员工自己也看不到累计**：一个开发者在多台机器跑 Claude Code，本机 `/usage` 只看到当前账户余量，跨机器累计是黑盒
- **没法做预算管控 / 合规审计**

具体触发点：本周内有员工两天用掉 36% 周 quota，但说不清究竟跑了什么任务。

### 目标用户

| 角色 | 描述 | 使用场景 |
|------|------|---------|
| IT 管理员 | 集中治理 AI 工具用量，应急拉黑陌生 device | 月度查看全公司分布、巡检异常 |
| 财务 | 成本分摊、预算执行追踪 | 月初导 CSV，按员工 / 项目分摊 |
| 工程经理 | 度量团队 AI 投入与产出关系 | 评估某项目的 AI 成本占比 |
| 员工本人 | 跨机器累计用量、个人成本意识 | 日常自查、按项目看分布 |
| 新员工 onboarding | 学习老员工的高效用法 | 看 Top 员工的工具/模型选择 |

### 业务流程

```mermaid
graph TD
    A[员工装 agent + 输入 token] --> B[Agent watch JSONL]
    B --> C[增量解析 + 批量 POST]
    C --> D[服务端 Bearer 校验]
    D --> E[Device 首次自动注册 + Event 入库]
    E --> F[Dashboard 实时聚合]
    F --> G[Admin / 员工查看]
    H[Cron 月度归档 1 年外数据] --> I[日级 Rollup]
```

### 详细需求

#### 0. 模块定位

**语义归属**：`it-operations` 一级模块的第二个 sub-capability（与 `cloud-costs` 并列）。
**文档目录**：`docs/modules/it-operations/ai-usage/`（嵌套目录，便于后续 sub-capability 扩展）。

**MVP 实现策略**（重要：`it-operations` 模块外壳尚未实现，避免空头复用）：

| 资源 | MVP 路径 | 未来迁移 |
|------|----------|----------|
| 后端模块 | `backend/src/modules/ai-usage/`（独立顶层模块） | it-operations 外壳就绪后可挂为子模块 |
| 前端 admin 路由 | `/admin/ai-usage` | 切到 `/it-operations/ai-usage` |
| 前端 me 路由 | `/me/ai-usage` | 不变 |
| API base | `/api/v1/ai-usage/...` | 不变 |
| Admin 菜单 | 顶层独立条目 "AI Coding 用量" | 移入 IT 运营 二级菜单 |
| Schema 文件 | 新建 `backend/prisma/schema/platform_ai_usage.prisma` | 不变 |
| i18n 目录 | `frontend/src/locales/aiUsage/`（按现有惯例每模块一目录） | 不变 |

- **权限点**通过 iam-admin seed 写入（独立无依赖）
- **审计**通过 `@Auditable()` + `@Sensitive()` 装饰器（audit-system 现有能力）
- **DataScope**通过现有 `DataScopeService` + 标准字段（列表查询零配置；**聚合查询必须 service 层手工 `where`**，见 `06-data-model.md` § 隔离与权限）

#### 1. 客户端 Node.js Agent（`ffctk`）

**安装与启动**：

```bash
# 一行命令安装
curl -fsSL https://ffai.faradayfuture.com/install.sh | bash

# 登录（一次性，把 token 写到 ~/.config/ffctk/credentials，权限 0600）
ffctk login ffai_xxxxxxxxxxxxxxxx

# 启动并自启（按平台调用 systemd / launchd / Windows Service）
ffctk start
ffctk enable    # 开机自启
ffctk status    # 看采集状态、最近上报、缓冲深度
ffctk logout    # 删除 credentials
```

**采集行为**：

- watch 路径：
  - Claude Code: `~/.claude/projects/**/*.jsonl`
  - Codex CLI: `~/.codex/sessions/**/*.jsonl`（具体路径以实测为准）
- 用 `chokidar` + 持久化 `~/.cache/ffctk/offsets.json`（含 inode + 字节 offset），避免重读和 truncate 错位
- 增量解析：每秒最多 1 次，30 秒内攒一批（≤ 500 条）批量 POST
- 离线缓冲：本地 sqlite 队列 `~/.cache/ffctk/queue.db`，上限 100MB；网络恢复自动续传；超上限丢最老 + 写入 `ffctk_dropped_total` 计数
- 字段提取（由 parser 插件按 tool 输出）：`sessionId / projectPath / model / ts / inputTokens / outputTokens / cacheCreationTokens / cacheReadTokens / rawMessageId`
- 成本估算：客户端**只算** `estimatedCostUsd`（依赖模型价目表，价目表内置 + 服务端可下发更新）；服务端不重算，trust client value
- 隐私铁律：永不读取 message content / system prompt / tool result body

**`rawMessageId` 生成规则**（客户端，跨工具统一）：

```
rawMessageId = <tool>:<sessionId>:<dedupKey>

dedupKey 来源（按优先级）：
  1. Claude Code: JSONL 行内 message.uuid（assistant turn）
  2. Codex CLI: JSONL 行内 id 或 turn_id 字段
  3. 兜底：sha256(jsonlLineRaw).slice(0, 16)
```

Parser 插件契约暴露 `getRawMessageId(parsedLine): string` 接口。**任何 parser 必须保证幂等**：同一行 N 次解析得到相同 `rawMessageId`。

**价目表更新机制**（解决"价格突变 24h 延迟"问题）：

- 客户端启动 + 每 24h 拉 `/api/v1/ai-usage/pricing` 写到 `~/.cache/ffctk/pricing.json`
- 服务端 ingestion 响应 header 含 `X-Pricing-Version: 2026-05-01`
- 客户端发现本地 version 旧于响应 version 时**立即重拉**
- 价目表初版手工维护在 `backend/src/modules/ai-usage/pricing/pricing.json`，按月 review

**进程模型**：

| 平台 | 模式 | 路径 |
|------|------|------|
| Linux | systemd user service | `~/.config/systemd/user/ffctk.service` |
| macOS | launchd user agent | `~/Library/LaunchAgents/com.ff.ffctk.plist` |
| Windows | Service（nssm 或 SCM）| 安装到用户级 |

**打包**（已收敛选型）：

- **工具**：`@yao-pkg/pkg`（社区维护 fork，`vercel/pkg` 已 archived；Node SEA 仅 Node 20+ 稳定且不支持 native module 如 `fsevents`，本场景不适用）
- **Node 版本**：lockfile 锁 Node 20 LTS
- **Native module 分发**：
  - macOS: 附带 `fsevents.node` 二进制（chokidar 内置 fallback 走 polling，但效率差 10×；强烈建议带 fsevents）
  - Linux: 走 inotify，glibc ≥ 2.17（covering Ubuntu 18.04+ / CentOS 7+）
  - Windows: 走 ReadDirectoryChangesW，无需额外 native
- **包大小**：每平台 ~50MB（Node runtime 嵌入），可接受
- **CI**：Gitea Actions 三 job 交叉编译，artifact 上传到 Gitea Release，install.sh 按 platform 拉对应 binary
- **代码签名 / 分发安全**：
  - **macOS**：MVP **不做** Apple Developer codesign + notarize（成本高），install.sh 自动 `xattr -d com.apple.quarantine ~/.local/bin/ffctk` 绕过 Gatekeeper；分发文档明示"内部工具，未签名"
  - **Windows**：MVP **不买** EV 证书；install.bat 先 `Unblock-File`，分发文档说明 SmartScreen 警告处置
  - **Linux**：无 OS 级签名要求
- **分发渠道**：
  - 主：Gitea Release artifact（`http://43.130.59.228/FFAIWorkspace/workspace/releases`）
  - install URL：`https://ffai.faradayfuture.com/install.sh` 或 `http://43.130.59.228/ffctk/install.sh`（按 UAT 域名待 ops 确认，PR 阶段统一占位 `${FFCTK_INSTALL_BASE}`）
  - install.sh 内嵌 SHA256 校验（防中间人篡改 + 自检完整性）
- **自更新**：MVP 不做；员工手动重跑 `curl ...install.sh | bash` 即可覆盖更新（保留 credentials）；二期加 `ffctk update` 命令

**配置文件**：

```
~/.config/ffctk/
  credentials       # 0600 权限，含 token（不进 git/dotfile sync）
  config.json       # api base url / batch size / log level
~/.cache/ffctk/
  offsets.json
  queue.db
  ffctk.log
```

#### 2. Personal Token 自助管理

**员工侧**（`/me/ai-usage/tokens`）：

- "生成新 token" → 弹窗输入 name（如 "我的 Mac" "公司 Linux"）→ 后端生成 32 字节随机 → 拼成 `ffai_<base64url>` → bcrypt 后存 hash → **一次性可见**，关闭弹窗后只能看到 prefix（前 12 位）
- token 列表：name、prefix、createdAt、lastUsedAt、撤销按钮
- 撤销立即生效（无服务端缓存）
- 一个员工**可以生成多个 token**（按机器分；MVP 不强制，员工也可以多台机器共用同一个）

**Admin 侧**（`/it-operations/ai-usage/tokens`）：

- read-only 看全公司 token 列表（按 user 分组），可"代撤销"应急
- 不能代员工**生成** token——身份归属必须由员工自己持有

**审计**：token 生成 / 撤销 / lastUsedAt 更新 写 audit_log

#### 3. 服务端 Ingestion API

**端点**：`POST /api/v1/ai-usage/events`

**请求**：
```http
Authorization: Bearer ffai_xxxxxxxxxxxxxx
X-Device-Id: <client-generated-uuid>
X-Hostname: <hostname>
X-Os-User: <os user name>
Content-Type: application/json
{
  "events": [
    {
      "tool": "claude-code",
      "sessionId": "...",
      "projectPath": "/home/chentao/Code/workspace",
      "model": "claude-opus-4-7",
      "ts": "2026-05-15T08:30:11Z",
      "inputTokens": 1024,
      "outputTokens": 2048,
      "cacheCreationTokens": 512,
      "cacheReadTokens": 8192,
      "estimatedCostUsd": 0.0438,
      "rawMessageId": "msg_xxx"
    }
  ]
}
```

**响应**：`202 Accepted`，body `{ accepted: N, deduped: M, rejected: K, deviceId: "..." }`

**处理顺序**：

1. token 校验（bcrypt compare）→ 失败 401
2. device 注册/续期：按 `X-Device-Id` upsert `AiUsageDevice`（owner = token.userId）；如 `blockedAt != null` → 403
3. rate limit：60 req/min/token（Redis 滑动窗口）→ 超限 429
4. event 批量 upsert：按 `rawMessageId` UNIQUE 去重，重复算 deduped 不算 rejected
5. 异常 event 进死信表 `AiUsageEventDLQ` + 计数，不阻塞整批

**关键约束**：
- 单批 ≤ 500 event（超出 413）
- ts 超过 now+5min 或 now-30day 视为可疑，进 DLQ
- 服务端不补算 cost（trust client）

#### 4. Admin Dashboard `/it-operations/ai-usage`

**首屏 KPI 卡**：
- 本月总用量（token / USD）、本月活跃员工数、本月活跃 device 数、本月活跃项目数
- 环比上月百分比（▲/▼）

**趋势曲线**：
- 默认本月每日总 USD / 总 token
- 切换：日 / 周 / 月粒度；近 7 天 / 30 天 / 90 天 / 1 年
- 切换维度叠加：按工具叠 / 按模型叠 / 按 Top N 员工叠

**下钻表**（切 Tab，每个表都有筛选+排序+分页）：
| Tab | 列 |
|-----|-----|
| 按员工 | user name / email / device 数 / 本期 token / 本期 USD / 环比 |
| 按项目 | projectPath / user / 本期 token / 本期 USD / 主用模型 |
| 按工具 | tool / 用户数 / 本期 token / 本期 USD |
| 按模型 | model / 用户数 / 本期 token / 本期 USD / 占比 |

**导出**：每个 Tab 顶部 "导出 CSV"，含当前筛选条件。

#### 5. 员工自查页 `/me/ai-usage`

- 本月 KPI 卡（个人维度）
- 个人趋势曲线（日/周/月）
- 项目分布饼图 + 表格
- 模型分布饼图
- Device 列表（本人所有 device + lastSeen + 拉黑状态）
- 子路由 `/me/ai-usage/tokens` 管理 token

#### 6. Admin Device 列表 `/it-operations/ai-usage/devices`

- 列：deviceId（短）/ hostname / osUser / 归属 user / firstSeen / lastSeen / 状态 / 操作
- 状态：ACTIVE / BLOCKED
- 操作：拉黑（输入 reason）/ 解黑
- 异常筛选：14 天无上报 / 跨多 user 切换（同一 device 关联到多个 user 是异常信号）

#### 7. 数据归档

- Cron 每月 1 日 03:00 UTC 跑 `archiveOldEvents()`
- 处理 `ts < now - 365d` 的 event：
  1. 按 (userId, projectPath, tool, model, date) 聚合写入 `AiUsageDailyRollup`
  2. 原 event 物理删除
  3. 写入归档审计日志：归档行数、覆盖时间区间
- Dashboard 查询 > 1 年时自动 fallback 到 rollup 表（粒度日级）

#### 8. 审计日志

通过 audit-system 现有装饰器自动写入（参考 `docs/modules/audit-system/12-integration-guide.md`）：

```typescript
@Controller('ai-usage')
export class AiUsageAdminController {
  @Post('me/tokens')
  @Auditable()                                  // 自动审计成功响应
  @RequirePermissions('ai-usage:view-own')
  async createMyToken(@Body() dto: CreateTokenDto) { ... }

  @Post('tokens/:id/revoke')
  @Auditable()
  @Sensitive()                                  // 敏感操作，audit body 不脱敏
  @RequirePermissions('ai-usage:manage-tokens-all')
  async adminRevokeToken(...) { ... }

  @Post('devices/:id/block')
  @Auditable()
  @Sensitive()
  @RequirePermissions('ai-usage:block-device')
  async blockDevice(...) { ... }
}
```

| 装饰器组合 | 触发 audit |
|--------|------|
| `@Auditable()` | token 自助生成 / 自助撤销 |
| `@Auditable() @Sensitive()` | admin 代撤 token、device 拉黑/解黑 |
| 后台 cron 归档 | service 内显式调 `this.auditService.write({...})`（无 controller 上下文） |

Ingestion 路径**不写**审计（每秒大量事件会爆 audit_log），仅在 device 首次注册 / token 首次使用时各写 1 条。

### 非目标（明确不做）

- ❌ 自动停机 / quota 阻断（侵入员工日常工具链）
- ❌ 采集消息内容（隐私铁律）
- ❌ 依赖 Anthropic / OpenAI 后台账单（维度不够、T+N 才出）
- ❌ MVP 阶段的告警 / 预算硬上限
- ❌ MVP 阶段的 HR offboarding 自动撤销 token（手动撤可应急）
- ❌ Cursor / GitHub Copilot 等其他 AI 工具（第二期+）

### 关键决策记录

| 决策点 | 选择 | 备选 | 理由 |
|--------|------|------|------|
| 模块归属（文档/语义） | it-operations sub-capability | 独立顶层 | 文档级归属保持，语义对齐云费用 / 订阅治理域 |
| 实现挂载（MVP） | 独立顶层模块 + `/admin/ai-usage` 路由 | 嵌套 it-operations 模块 | it-operations 外壳尚未实现，避免空头复用；URL alias 可后续无缝迁移 |
| MVP 工具 | Claude Code + Codex CLI | 仅 Claude Code | 公司同时在用，分两期工时差不多；schema 加 tool 字段隔离 |
| 客户端语言 | Node.js + 单 binary 打包 | Go / Python | 复用前后端技术栈，团队熟悉；pkg/SEA 解决跨平台分发 |
| 平台范围 | Linux + macOS + Windows | 仅 Linux+macOS | 公司 Codex CLI 直接跑在 Mac/Windows，必须覆盖 |
| 安全模型 | Personal Token (Bearer) | 内网 IP 白名单 / 零限制 | 强身份约束 + 零摩擦 + 离职可控；零限制有伪造风险，IP 白名单跨网络不友好 |
| Device 状态 | 自动注册 / 无 PENDING | admin 审批 PENDING | token 已经强约束身份，再加审批是冗余摩擦 |
| 数据保留 | 1 年热 + 永久日级归档 | 90 天 / 永久 | 平衡存储成本和复盘需求 |
| Project 路径粒度 | admin 看完整路径 | basename / hash | 归属完整性优先，员工知情同意（首次启动 ffctk 显示隐私说明） |
| 告警机制 | 第二期 | MVP 含 | 缩小 MVP 范围，告警需要独立决策（阈值/通知渠道/屏蔽窗口） |

### 隐私与合规

- **采集白名单**：仅 `sessionId / projectPath / model / ts / tokens × 4 / cost / rawMessageId`，schema 层强制不能存其他字段
- **客户端首次启动**：`ffctk login` 后第一次 `ffctk start` 时打印隐私声明，需 enter 确认
- **员工知情**：员工自查页固定展示「我们采集了什么 / 没采集什么」FAQ
- **数据导出权**：员工可随时下载自己的全部数据（GDPR-like）
- **数据删除权**：员工撤销所有 token 后，可申请删除历史 event（admin 审批，写 audit）

### 性能 / 容量

| 指标 | 估算 |
|------|------|
| 员工数 | 100（一期试点 5-10） |
| 单员工日 event | ~ 200 |
| 日总 event | ~ 20k |
| 年增 event 行 | ~ 7M |
| 单批 ingestion | ≤ 500 event |
| Rate limit | 60 req/min/token |
| 客户端缓冲上限 | 100MB |
| API 响应 P95 | < 200ms |
| Dashboard 首屏 P95 | < 1s（依赖物化视图 / Redis cache） |
| 归档 cron 单次运行 | < 5min（≤ 100w 行） |

### 分阶段规划

| 阶段 | 目标 | 工时 |
|------|------|------|
| **Phase 1（本批 PR）** | 上述 in-scope 全部 | **8-10 天单人** |
| Phase 2 | 告警/预算阈值 + 团队权限细化 + Cursor/Copilot + HR offboarding 联动 | 5-7 天 |
| Phase 3 | ROI 度量（联动 daily-report / retro） | 5-7 天 |

### 风险与缓解

| 风险 | 影响 | 缓解 |
|------|------|------|
| JSONL 格式随 Claude Code / Codex 升级变化 | parser 解析错误率上升 | parser 插件化 + 版本号检测；服务端进 DLQ 不阻塞 |
| 客户端三平台打包复杂度 | 工时超预算 | 先做 Linux + macOS（覆盖 80%），Windows 紧跟 |
| Device 重装后 device_id 变化 | dashboard 出现"陌生 device" | 用 `hostname + osUser` 软指纹自动复用；admin 可手工合并 |
| 客户端时钟漂移 | event ts 不准 | 服务端记录 receivedAt，dashboard 双口径 |
| Token 泄漏 | 伪造数据 | 撤销立即生效 + lastUsedAt 异常变化告警（第二期） |
| Cost 估算与 Anthropic 账单不一致 | 财务对不上 | 文档明示"估算 ≠ 账单"；账单口径走 Phase 2 接入官方 API |

### 验收清单（L3 人工验收）

- [ ] 提单人在 `/it-operations/ai-usage` 30 秒内说出上月 Top 3 员工 / 项目 / 模型
- [ ] 员工在 `/me/ai-usage` 看到跨多台机器累计（试点期间至少有 2 个员工有 2+ device）
- [ ] `curl install.sh \| bash` + `ffctk login` + `ffctk start` 三步在新 mac / linux 上跑通
- [ ] 关机一晚 → 重启 → 离线缓冲数据自动续传
- [ ] admin 拉黑某 device → 该 device 后续上报全部 403
- [ ] 切换 zh-CN ↔ en-US，dashboard 所有文案完整、无 missing key warning
- [ ] CSV 导出在 Excel 中乱码自查
- [ ] 试点员工抽查 audit_log，token 生成/撤销 / device 拉黑 全部有记录
- [ ] 隐私 FAQ 文案经法务/HR 简单 review

---

## 状态流转检查清单（同 Issue #338 状态机）

- [x] 需求待澄清 → 待领取
- [x] 待领取 → PRD 中（2026-05-15 chentao.jia claim）
- [ ] PRD 中 → 契约设计中（待 PRD review ✅）
- [ ] 契约设计中 → 开发中
- [ ] 开发中 → 待验收
- [ ] 待验收 → 关闭

---

## v1.1 富 metadata 增量（2026-05-16）

**目标**：让 admin dashboard 不只看"烧了多少 token"，还能回答"哪些工具占比高 / session 多长 / 思考多密 / priority tier 烧了多少钱 / 哪些分支最贵"。

**客户端扩展**（`ffctk` watcher + parser）：
- 新增 9 个可选字段：`gitBranch` / `agentVersionEvent` / `worktreeLabel` / `cwdBasename` / `turnIndex` / `toolUseCount` / `toolNames` / `stopReason` / `serviceTier`
- 数据源全部来自 Claude Code JSONL 的**顶层 metadata** 或 `message.usage` / `message.content[].type='tool_use'` 的 `name` 字段
- **隐私铁律**：parser 层 hard-coded 仅读取上述字段；从不读取 `content[].text` / `content[].thinking` / `tool_use.input` / `tool_result.content`，**单测覆盖**这一边界

**服务端扩展**：
- `ai_usage_events` 表加 9 个可空列 + 3 个新索引（`session_id`/`git_branch`/`service_tier`）
- 6 个新聚合端点（同时挂 admin 和 `/me/...`，权限由 `view-all` / `view-own` 自动 scope）
- DTO 严格 allowlist，未知字段被 strip，超长字段拒绝
- L1 测试覆盖每个新字段从 ingestion → DB 落盘的正确性（ingestion.test.ts case 13-16；dashboard.test.ts case 10-15）

**Dashboard 增图（admin 总览页）**：
- 工具频次热力图（ECharts pie / bar）
- Session 时长 + turn 分布（ECharts dual histogram）
- Turn 间隔分布（ECharts histogram）— "思考密度"洞察
- Service Tier 配比（ECharts pie，priority vs standard 成本占比）
- Stop Reason 配比（ECharts bar，`max_tokens` 高 = 拆 turn 信号）
- Git Branch 烧 token 热力图（ECharts bar，top 20 分支）

**不在 v1.1 范围**：
- Claude Code 5h quota / context_window 利用率：transcript 没有可靠字段，待 API 接入或 status line hook 后补
- `user message interrupt` 检测：JSONL 不直接给信号，需在客户端额外 watch
- 工程上下文中"是否产生 commit"：跨进程边界，需 git hook 集成
