同步错误报告分页与存储决策文档
记录 UUID OSS key、元数据索引和分页响应约定 从 review.txt 移除已完成的 2、4、5、6、9 项
This commit is contained in:
@@ -19,11 +19,12 @@ AI Game Creator Shell 采用 IDEA 风格的当前进程错误报告:错误事
|
||||
- 登录态客户端使用 `POST /api/error-reports`,请求 DTO 位于 `shared-contracts::error_reports`。
|
||||
- api-server 对请求体设置 24 MiB 上限,并校验 schemaVersion、submissionId、事件/日志数量和 20 MiB 压缩包上限;事件字段、用户说明和日志名/内容均做长度限制与基础脱敏,归档使用 `events.jsonl`(每行一个事件)。结构化事件只保存在当前进程内,用户提交时才生成 `events.jsonl`,不在磁盘单独持久化。submissionId 提供重放幂等。
|
||||
- 归档构建会短暂使用一个受 20 MiB 上限约束的内存 `Vec<u8>`,随后立即写入私有本地归档;不把 ZIP 长期留在内存。这样既控制峰值,又支持进程重启后后台查看/下载和 OSS 上传失败后的本地取证。
|
||||
- 归档对象使用固定私有 OSS key:`agc/error-reports/v1/{yyyy}/{mm}/{dd}/{batchId}.zip`;api-server 先写 `uploading` 元数据,上传成功后记录 `ossObjectKey`、SHA-256、大小和 `ready` 状态。完整事件、说明和日志不进入元数据记录。
|
||||
- 本地 `error-reports/index.json` 保存元数据索引;创建时用索引完成 submission 幂等查找,管理员列表从索引读取并分页。索引缺失时会从现有元数据文件一次性重建。
|
||||
- 归档对象使用固定私有 OSS key:`agc/error-reports/v1/{batchId}.zip`;key 只由报告 UUID 决定,不包含时间戳。api-server 先写 `uploading` 元数据,上传成功后记录 `ossObjectKey`、SHA-256、大小和 `ready` 状态;相同 submission 重放对已 `ready` 报告直接返回,不重复上传。完整事件、说明和日志不进入元数据记录。
|
||||
- `agc` 是服务端专用私有前缀;公共直传票据、通用 object-key 规范化和 legacy 公开路径均拒绝该前缀。归档内同名日志会自动加数字后缀,读取本机诊断日志时拒绝符号链接/非普通文件。
|
||||
- 后台接口:`GET/PATCH /admin/api/error-reports/{batchId}`、`GET /admin/api/error-reports` 和受保护的 `/download`。
|
||||
- 后台接口:`GET/PATCH /admin/api/error-reports/{batchId}`、`GET /admin/api/error-reports` 和受保护的 `/download`。列表支持 `limit`/`offset` 分页并返回 `total`、`hasMore`。
|
||||
- 这些是 api-server 内部登录/管理员路由,不属于 `/api/external/v1`,不纳入 External OpenAPI;管理员详情对不存在返回 404,对归档/元数据损坏返回 500。
|
||||
- admin viewer 仅接受 error-reports Tab 权限,支持列表筛选、详情、状态 `new/in-progress/resolved`、处理备注和受控下载;列表行支持键盘 Enter/Space 打开详情,详情事件预览最多显示 20 条,完整内容通过诊断包下载获取。
|
||||
- admin viewer 仅接受 error-reports Tab 权限,支持列表筛选、分页、详情、状态 `new/in-progress/resolved`、处理备注和受控下载;不存在的更新目标返回 404,存储损坏返回 500。列表行支持键盘 Enter/Space 打开详情,详情事件预览最多显示 20 条,完整内容通过诊断包下载获取。
|
||||
- 当前兼容实现仍在 api-server 配置目录旁保留元数据与本地归档副本,便于无 OSS 配置的开发环境运行;生产配置启用 OSS 后以 OSS 对象为完整内容来源。SpacetimeDB `error_report` 私有表接入及 30 天 OSS/元数据清理 worker 为后续门禁,HTTP DTO 与管理员权限保持不变。
|
||||
|
||||
## 验收
|
||||
|
||||
-30
@@ -8,36 +8,12 @@
|
||||
|
||||
当前仅限制单次请求体(24 MiB),没有按用户限流、存储配额或全局容量上限。单个账号可以持续触发 ZIP/SHA-256/OSS 写入并使本地磁盘和对象存储增长。需要确定:按用户还是按 IP 限流、窗口与返回状态(通常 429)、配额维度、超额时是否拒绝或清理旧报告,以及生产配置和监控指标。
|
||||
|
||||
## 2. 管理员错误报告列表需要分页契约(中风险)
|
||||
|
||||
位置:`apps/admin-web/src/pages/AdminErrorReportsPage.tsx` 及 admin API。
|
||||
|
||||
列表目前最多读取服务端默认 100 条,没有 offset/cursor 和 total;超过 100 条后旧报告不可达。需要确定采用 offset 还是 cursor、是否返回 total/hasMore、默认页大小、筛选与排序保持方式,并同步 shared-contracts、前后端测试和 UI。
|
||||
|
||||
## 3. 并发文件 I/O 与归档解析迁移到 `spawn_blocking`(中风险)
|
||||
|
||||
位置:`server-rs/crates/api-server/src/error_reports.rs`。
|
||||
|
||||
create/list/get/read_archive/mark_* 在 async handler 中持有 Tokio mutex 并执行同步文件 I/O、ZIP 解析和权限操作,会阻塞 worker 且串行化请求。迁移需要重新划分锁的临界区、处理取消语义和错误映射,并验证并发下幂等与清理行为。
|
||||
|
||||
## 4. 元数据全目录扫描改为索引(中风险)
|
||||
|
||||
位置:`ErrorReportStore::create/list`。
|
||||
|
||||
每次创建和列表都扫描并反序列化所有元数据,成本随 30 天保留量线性增长。可选方案包括把 `user_id + submission_id` 哈希进文件名、维护内存索引或引入持久索引;需要评估进程重启恢复、历史文件兼容和清理一致性。
|
||||
|
||||
## 5. 幂等重放对已 ready 报告短路(中风险)
|
||||
|
||||
位置:`ErrorReportStore::create`/上传流程。
|
||||
|
||||
相同 `submission_id` 重放时当前会再次读取、哈希和上传归档,可能在跨日时生成新 OSS key、遗留旧对象,或把原本 ready 的报告降级为 failed。修复会改变重放响应和存储状态迁移,需要确定 ready/failed/uploading 各状态的权威行为、并发重放锁和 OSS 清理策略。
|
||||
|
||||
## 6. 归档缺少 `events.jsonl` 时应视为损坏(中风险)
|
||||
|
||||
位置:`parse_archive`。
|
||||
|
||||
当前缺少 `events.jsonl` 会静默返回空事件,管理员可能把损坏包当成有效报告。改为报错会改变现有损坏归档的读取结果和 HTTP 状态,需要确定是否仅在 `event_count > 0` 时拒绝、错误码/提示和历史归档处理方式。
|
||||
|
||||
## 7. 日志脱敏从整段替换改为局部掩码(中风险)
|
||||
|
||||
位置:`sanitize_report_text_with_limit`。
|
||||
@@ -50,12 +26,6 @@ create/list/get/read_archive/mark_* 在 async handler 中持有 Tokio mutex 并
|
||||
|
||||
当前每次 console 调用都同步打开/追加/flush 文件,读取命令也在主线程执行。迁移到 `spawn_blocking` 或队列批量写入会改变调用时序、失败可见性、退出时刷盘和测试方式,需要确定丢日志容忍度、队列上限、关闭 flush 和 Tauri command 返回语义。
|
||||
|
||||
## 9. 管理员更新缺失报告的错误契约(低但涉及 HTTP 语义)
|
||||
|
||||
位置:`admin_update_error_report` 与 `ErrorReportStore::update`。
|
||||
|
||||
当前所有 update 错误都映射为 400 并可能泄露底层文件系统文本;合法但不存在的 `batch_id` 应为 404,损坏/内部错误应为 500。需要引入 typed error、统一错误消息和对应契约测试,属于管理员 API 状态码语义调整。
|
||||
|
||||
## 10. 诊断日志读取的安全打开实现(中风险)
|
||||
|
||||
位置:`apps/ai-game-creator-shell/src-tauri/src/main.rs::read_diagnostic_logs`。
|
||||
|
||||
Reference in New Issue
Block a user