feat: 新增 POST /assets/batch 批量获取素材详情接口 #1418

Merged
xiaoxia merged 1 commits from fix/assets-batch-endpoint into develop 2026-08-18 13:42:54 +08:00
Owner

问题

前端 usePreviewAssets.ts 调用 POST /assets/batch 时返回 405 Method Not Allowed。

根因:后端没有 /batch GET/POST 端点,请求命中了 GET /{asset_id}batch 被当成 asset_id),但 HTTP method 不匹配,返回 405。

修复

新增 POST /assets/batch 端点,支持根据 ID 列表批量获取素材详情。

接口规格

  • 路由POST /api/v1/assets/batch
  • 请求体{ "ids": ["id1", "id2", ...] }(最多 200 个 ID)
  • 响应List[AssetResponse],包含 file_urldurationwidthheightfpscodecstatus 等完整元数据
  • 认证:需要登录

改动文件

  • apps/api/app/schemas/asset.py:新增 BatchGetRequest schema
  • apps/api/app/api/routes/assets.py:新增 batch_get_assets 端点

前端适配

前端 usePreviewAssets.ts 已有 fallback 逻辑(批量失败则逐个获取),新增接口后无需修改前端代码。

## 问题 前端 `usePreviewAssets.ts` 调用 `POST /assets/batch` 时返回 405 Method Not Allowed。 **根因**:后端没有 `/batch` GET/POST 端点,请求命中了 `GET /{asset_id}`(`batch` 被当成 asset_id),但 HTTP method 不匹配,返回 405。 ## 修复 新增 `POST /assets/batch` 端点,支持根据 ID 列表批量获取素材详情。 ### 接口规格 - **路由**:`POST /api/v1/assets/batch` - **请求体**:`{ "ids": ["id1", "id2", ...] }`(最多 200 个 ID) - **响应**:`List[AssetResponse]`,包含 `file_url`、`duration`、`width`、`height`、`fps`、`codec`、`status` 等完整元数据 - **认证**:需要登录 ### 改动文件 - `apps/api/app/schemas/asset.py`:新增 `BatchGetRequest` schema - `apps/api/app/api/routes/assets.py`:新增 `batch_get_assets` 端点 ### 前端适配 前端 `usePreviewAssets.ts` 已有 fallback 逻辑(批量失败则逐个获取),新增接口后无需修改前端代码。
xiaoxia added 1 commit 2026-08-18 13:04:16 +08:00
feat: 新增 POST /assets/batch 批量获取素材详情接口
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 25s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m21s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m23s
AI Code Review / AI Code Review (pull_request) Failing after 1m49s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m16s
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m35s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m36s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 7m4s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 5m41s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 3m21s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 10m29s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 14m21s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Successful in 6s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 58s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 19s
8a0358b9bf
前端 usePreviewAssets.ts 调用 POST /assets/batch 时返回 405 Method Not Allowed,
原因是后端没有 /batch GET/POST 端点,请求命中了 GET /{asset_id}(batch 被当成 asset_id)。

新增:
- BatchGetRequest schema:接收 { ids: string[] },最多 200 个 ID
- POST /assets/batch 端点:调用 asset_repository.find_by_ids() 批量查询
- 返回 List[AssetResponse],包含 file_url、duration、width、height 等完整元数据

改动文件:
- apps/api/app/schemas/asset.py:新增 BatchGetRequest
- apps/api/app/api/routes/assets.py:新增 batch_get_assets 端点
Collaborator

【阻塞级判定】

  • 是否存在阻塞级问题:是
  • 阻塞级问题数量:1 个

📊 审查概览

  • 整体评价:需修改
  • 建议级问题数量:1 个

🔴 阻塞级问题(必须修复)

  1. [apps/api/app/api/routes/assets.py: 374-382] 权限校验缺失导致越权访问
    • 问题类型:安全漏洞 / 逻辑bug
    • 问题描述:新增的 batch_get_assets 接口直接根据 ID 列表查询素材并返回,但未对查询结果进行权限校验(如调用 check_project_access)。攻击者可以通过遍历 ID 获取项目中无权访问的其他素材详情,造成敏感信息泄露。
    • 修改建议:参考同文件中 update_asset_review_statusbatch_delete_assets 的实现,在返回数据前,必须遍历 items 并对每个 item 调用 check_project_access(item.project_id, authenticated_user) 进行权限校验,或者确保 asset_repository.find_by_ids 方法内部已包含基于用户的权限过滤逻辑。

💡 改进建议(不阻塞合并)

  1. [apps/api/app/api/routes/assets.py: 375] 类型提示一致性
    • 具体内容:函数返回值注解使用了 Python 3.9+ 的内置泛型 list[AssetResponse],而 response_model 使用了 typing.List。建议保持一致,例如统一使用 List[AssetResponse](如果需要兼容旧版 Python)或统一使用 list[AssetResponse]

良好实践

  1. Schema 层面做了较好的限制BatchGetRequest 中对 ids 字段添加了 min_length=1max_length=MAX_BATCH_SIZE,有效防止了空请求或过大的请求负载,符合防御性编程原则。

🤖 由 AI 代码审查机器人自动生成 | 2026-08-18 05:06:34 | 模型:

### 【阻塞级判定】 - 是否存在阻塞级问题:是 - 阻塞级问题数量:1 个 ### 📊 审查概览 - 整体评价:需修改 - 建议级问题数量:1 个 ### 🔴 阻塞级问题(必须修复) 1. **[apps/api/app/api/routes/assets.py: 374-382] 权限校验缺失导致越权访问** - 问题类型:安全漏洞 / 逻辑bug - 问题描述:新增的 `batch_get_assets` 接口直接根据 ID 列表查询素材并返回,但未对查询结果进行权限校验(如调用 `check_project_access`)。攻击者可以通过遍历 ID 获取项目中无权访问的其他素材详情,造成敏感信息泄露。 - 修改建议:参考同文件中 `update_asset_review_status` 或 `batch_delete_assets` 的实现,在返回数据前,必须遍历 `items` 并对每个 item 调用 `check_project_access(item.project_id, authenticated_user)` 进行权限校验,或者确保 `asset_repository.find_by_ids` 方法内部已包含基于用户的权限过滤逻辑。 ### 💡 改进建议(不阻塞合并) 1. **[apps/api/app/api/routes/assets.py: 375] 类型提示一致性** - 具体内容:函数返回值注解使用了 Python 3.9+ 的内置泛型 `list[AssetResponse]`,而 `response_model` 使用了 `typing.List`。建议保持一致,例如统一使用 `List[AssetResponse]`(如果需要兼容旧版 Python)或统一使用 `list[AssetResponse]`。 ### ✅ 良好实践 1. **Schema 层面做了较好的限制**:`BatchGetRequest` 中对 `ids` 字段添加了 `min_length=1` 和 `max_length=MAX_BATCH_SIZE`,有效防止了空请求或过大的请求负载,符合防御性编程原则。 --- <sub>🤖 由 AI 代码审查机器人自动生成 | 2026-08-18 05:06:34 | 模型: </sub> <!-- AI_CODE_REVIEW_AUTO_COMMENT -->

🚀 预览环境已部署

项目 详情
PR号 #1418
预览链接 https://pr-1418.preview.xiaoxiajianji.com
API环境 staging

💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。

🔄 每次提交新代码后预览环境会自动更新。

🗑️ PR 关闭或合并后,预览环境会自动清理。

🚀 **预览环境已部署** | 项目 | 详情 | |------|------| | PR号 | #1418 | | 预览链接 | [https://pr-1418.preview.xiaoxiajianji.com](https://pr-1418.preview.xiaoxiajianji.com) | | API环境 | staging | > 💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。 > > 🔄 每次提交新代码后预览环境会自动更新。 > > 🗑️ PR 关闭或合并后,预览环境会自动清理。
auto-approve-bot approved these changes 2026-08-18 13:15:31 +08:00
auto-approve-bot left a comment
Collaborator

CI全绿,自动审批通过。

CI全绿,自动审批通过。
auto-approve-bot approved these changes 2026-08-18 13:15:31 +08:00
auto-approve-bot left a comment
Collaborator

CI全绿,自动审批通过。

CI全绿,自动审批通过。
xiaoxia merged commit 8ef96e8569 into develop 2026-08-18 13:42:54 +08:00

🗑️ 预览环境已清理

PR #1418 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #1418 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Sign in to join this conversation.