Files
meida_backend/apps
xsl a1d0171fc5
CI / lint / typecheck / import-linter / tests / secrets (push) Canceled after 0s
feat(uploads): 本地磁盘直传(COS 降级路线)+ 报告照片存在性校验
- POST /uploads/direct:原始字节 body + Content-Type 申报 + scene query(默认 report_photo),场景/类型/大小三重校验复用 storage 既有规则,落盘 var/uploads/<scene>/<user_id>/<uuid>.<ext>(config 新增 upload_dir),key 布局与 COS 同构;不加 python-multipart 依赖
- storage/local.py:save_direct_upload + require_local_upload(resolve 归并 + is_relative_to 归属收敛 + 存在性校验,越界/模拟/不存在一律 404)
- report/service.create_report:资格校验后、配额预扣前插入照片存在性校验(模拟 key 被拦且不消耗额度;regenerate 复用已验 photo_meta 不复核)
- 测试:test_upload_direct 14 单测 + test_upload_direct_flow 4 集成(真 key 全链路/假 key 404 零流水/401/40010)

偏差说明:test_report_flow._create_report 改走 /uploads/direct 拿真 key(存在性校验必然封死假 key),40920 与幂等重放两条断言语义未动。
2026-09-12 00:24:01 +08:00
..

apps/ — 可部署的进程

目录 进程
api/ FastAPI 应用:路由、依赖注入、中间件
worker/ Celery 任务定义与四队列配置(gpu / cpu / io / beat)
admin/ 极简运营后台(占位,FR-ADM-01~05)

API 层的职责边界(架构 §3.1 L3)

只做编排:认证鉴权、参数校验、幂等、配额校验与预扣、统一响应、OpenAPI。

不能放什么

  • 业务规则。路由函数里出现 if 判断业务条件,几乎总是应该下沉到 packages/<域>/service.py 或 packages/domain/。
  • 直接写 SQL 或用 ORM 查表。走域的 service。
  • 直接调用外部 API。LLM 走 packages/llm;未来的审核、视觉、换装同理。
  • 裸 dict 返回。所有响应必须经过 packages.shared.response.ok() / fail()。

契约先行(NFR-MAINT-01)

先在 apps/api/schemas.py 定义 Pydantic schema,再写实现。客户端类型由 OpenAPI 生成,schema 一变客户端立刻可见。

Worker 的规矩

  • 每个长耗时任务都必须落 tk_task,走 packages/task 的状态机。 不要自己维护状态字段。
  • 失败必须退还配额(billing.refund(),FR-BILL-05)。 apps/worker/tasks.py 里的 ping_task 是形状示例。
  • 队列按资源画像分:GPU 推理进 gpu,视觉/渲染进 cpu,外部调用进 io。 混队列会让「换装排队把报告拖慢」。