# TCOC Time Correlation 设计总结

## Current Design

- `deployment/evolver/scripts/overlap/tcoc_time_correlation.py` 负责导出 Investibook 用户 chat message 和 TCOC ticket drilldown 数据，并基于 `cluster_id` 与标准化 UTC+8 时间窗口做重叠匹配。
- 脚本无第三方依赖，只依赖 Python 3 标准库，方便在本地 worktree、backend pod 或 CI shell 中运行。
- 脚本支持七个子命令：
  - `export-prod`：只读导出一周 chat raw data 和 TCOC raw data。
  - `normalize-chat`：从 chat message 中抽取 `cluster_id` 和时间窗口。
  - `normalize-tcoc`：从 TCOC description 中抽取时间窗口，必要时回退到 `jira_created_at`。
  - `correlate`：对标准化后的 chat/TCOC 数据做 cluster + time overlap 匹配。
  - `run-all`：对已有 raw export 执行标准化和匹配。
  - `run-week`：串联 prod 导出、标准化和匹配。
  - `validate`：校验标准化输出和匹配输出字段集合。
- prod 导出默认使用：
  - EKS context：`arn:aws:eks:us-west-2:557537366020:cluster/devops-prod`
  - namespace：`investibook`
  - DB path：`/data/db/investibook.db`
- `week_start_date` 表示 UTC+8 自然周起点；chat 查询前会转换成 UTC `created_at` 区间。
- chat raw export 只读 `messages_v2`，并 left join `workspaces`，只导出 completed user message，不读取或合并 `feishu_chat_messages`。
- TCOC raw export 在 backend pod 中调用 `_db_admin_dashboard_ticket_trends_drill_down()` 获取 dossier，再通过 `incident_dossier_issues` join `jira_tickets` 读取 issue 数据。
- 默认输出目录是 `exports/investibook_prod_week_<week_start_date>`，主要文件包括：
  - `chat_user_messages_week.json`
  - `dossier_tcoc_for_week.json`
  - `time_standard_chat.json`
  - `time_standard_tcoc.json`
  - `time_standard_matches.json`

## Risks

- 时间解析依赖大量启发式正则，需要同时处理英文、中文、URL query 参数、epoch 秒/毫秒、显式时区、相对时间和自然语言时间段，存在误识别风险。
- chat 侧只有在同时抽到 cluster 和时间窗口，并且内容像诊断/查询请求时才进入标准化输出；纯材料粘贴、巡检和容量规划类消息会被过滤。
- chat normalization 会按 `(content, cluster_id)` 去重，不会保留同内容同 cluster 的重复 message。
- TCOC description 可能是 Jira rich text document，脚本会 flatten 成纯文本后解析；复杂结构可能导致上下文丢失。
- TCOC 时间候选通过 score 选择：故障上下文、业务上下文、range、显式时区都会影响排序；如果 description 内同时包含多个时间，可能选错主窗口。
- 当 TCOC description 没有可解析时间时，会回退到 `jira_created_at`，这能保证输出完整，但不一定代表故障发生窗口。
- 匹配规则要求 `cluster_id` 完全相等且标准化时间区间有交集，因此缺失 cluster、错误 cluster 或时间窗口解析偏差都会导致漏匹配。
- prod TCOC 导出依赖 backend 内部 helper 的行为和固定 range 参数；helper 语义变化会影响 raw ticket 范围。

## Target Contract

- prod 访问必须保持只读，不修改 DB、pod、Kubernetes resource 或 Investibook 数据。
- chat raw export 只能查询 `messages_v2`，不能混入 `feishu_chat_messages`。
- raw chat rows 不做去重；去重只允许发生在 chat normalization 阶段。
- 所有时间标准化输出都使用 UTC+8，格式统一为：
  - 单点：`YYYY-MM-DD HH:MM:SS UTC+08`
  - 同日区间：`YYYY-MM-DD HH:MM:SS-HH:MM:SS UTC+08`
  - 跨日区间：`YYYY-MM-DD HH:MM:SS-YYYY-MM-DD HH:MM:SS UTC+08`
- `time_standard_chat.json` 每条记录必须包含：
  - `id`
  - `message_id`
  - `cluster_id`
  - `content`
  - `created_at`
  - `standard_time`
- `time_standard_tcoc.json` 每条记录必须包含：
  - `id`
  - `issue_key`
  - `cluster_id`
  - `standard_time_source`
  - `standard_time`
- `time_standard_matches.json` 每条记录必须包含：
  - `message_id`
  - `issue_key`
  - `cluster_id`
  - `standard_time`
- correlation 只在 `cluster_id` 字符串完全相等且两个标准化 interval 有交集时生成匹配。
- 空匹配是合法结果，应写出 `[]`。

## Implementation Steps

1. 用 `parse_week_start()` 标准化 `week_start_date`，并用 `chat_utc_bounds_for_utc8_week()` 生成 chat 查询所需 UTC 边界。
2. prod 导出前发现 running/ready backend pod，并用只读 SQLite 连接确认 `messages_v2`、`workspaces`、`incident_dossier_issues`、`jira_tickets` 的必要列存在。
3. 导出 chat raw data：查询 completed user message，写入 `chat_user_messages_week.json`。
4. 导出 TCOC raw data：调用 dashboard drilldown helper 获取 dossier，再 join Jira ticket，写入 `dossier_tcoc_for_week.json`。
5. 标准化 chat：从内容中抽取 cluster ID 和时间表达，排除巡检、纯材料、容量规划等非诊断请求，将保留项写入 `time_standard_chat.json`。
6. 标准化 TCOC：flatten description，抽取并评分时间候选；如果没有候选则使用 `jira_created_at`，写入 `time_standard_tcoc.json`。
7. 解析两边 `standard_time` 为 interval，在 `cluster_id` 相同且 interval overlap 时写出交集窗口到 `time_standard_matches.json`。
8. `run-week` 串联 prod export、chat normalization、TCOC normalization 和 correlation；`run-all` 复用已有 raw export 只做本地处理。

## Verification Checklist

- `python3 deployment/evolver/scripts/overlap/tcoc_time_correlation.py --help` 能显示所有子命令。
- `export-prod` 输出 `chat_user_messages_week.json` 和 `dossier_tcoc_for_week.json`，并报告 record count。
- chat 查询窗口符合 UTC+8 自然周语义，例如 `2026-06-15` 对应 UTC `[2026-06-14T16:00:00Z, 2026-06-21T16:00:00Z)`。
- `normalize-chat` 输出字段严格等于 `id/message_id/cluster_id/content/created_at/standard_time`。
- `normalize-tcoc` 输出字段严格等于 `id/issue_key/cluster_id/standard_time_source/standard_time`。
- `correlate` 输出字段严格等于 `message_id/issue_key/cluster_id/standard_time`。
- `validate --input-dir <dir>` 对三份 derived output 返回 `fields_exact = true`。
- 显式 UTC、UTC+8、UTC+9、epoch 秒/毫秒、同日区间、跨日区间和中文“今天/昨天/下午”时间能被标准化为 UTC+8。
- TCOC description 无可解析时间时，`standard_time_source` 为 `jira_created_at`。
- cluster 相同但时间不重叠时不会生成 match；cluster 不同即使时间重叠也不会生成 match。
