- 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 与幂等重放两条断言语义未动。
POST /uploads/presign:场景/类型/大小三重校验 + 可审计 object_key 布局 + SDK 隔离在 CosSigner Protocol 后(FR-SYS-03,T-P1-27)。 实现:packages/storage/schemas.py(PresignRequest/PresignResponse)、 packages/storage/service.py(CosSigner Protocol / QcloudCosSigner / StorageService.build_presign,bucket 四别名映射到 cos_bucket_*, object_key 写死 {scene}/{user_id}/{yyyyMMdd}/{uuid4hex}.{ext})、 apps/api/routers/uploads.py(POST /presign,CurrentUserId 认证 + ok 信封)。 测试:tests/unit/test_upload_presign.py 16 例全部经 FakeSigner 注入, 零网络、零 SDK client 构造;覆盖 key 布局逐段断言、三重校验统一 40010、 bucket 别名映射、白名单字符串解析(空串/空格容错)、配置错误分支、 schema 层 size>=1。门禁全绿:ruff check/format、mypy(宽松 48 文件 + domain strict 7 文件)、lint-imports 4 契约、pytest 185 passed (基线 169 + 新增 16)。 偏差说明: 1) SDK 实际无 qcloud_cos.method 模块,Method 按官方文档传字符串 "PUT"; get_presigned_url 参数名为 Expired(非任务文档写的 Expire);配置类 导出名为 CosConfig(非 CosS3Config)。按文档 §3 "以实际 SDK 签名为准" 处理,已用假密钥端到端冒烟验证(纯本地签名计算,零网络)。 2) build_presign 增加可选 keyword-only 参数 now(默认 None=当前 UTC), 供单测注入固定时钟(对齐 DailyBudgetGuard 的 clock 注入惯例), 不改变文档签名的调用兼容性。 3) 两处防御分支文档未规定,均配了单测:场景 bucket 别名非法报 CONFIG_ERROR 而非 40010(配置错误不应让客户端背 4xx);COS 密钥为空 在 SDK 构造前报 CONFIG_ERROR,避免未处理的裸 500。
多 agent 并行批次的协调提交(消除全部共享文件冲突面): - 迁移 0004:id_session + ob_event 两表(T3/T4 用,任务不再写迁移) - ORM:UserSession / ObEvent;错误码:九个新码(40xxx/60006,含 meta) - 配置:四档 tiers / refresh TTL / 任务奖励注册表 / 埋点上限 / COS 直传全套 - 骨架:packages/analytics + packages/storage + events/uploads 空路由(已注册) - deps:AnalyticsServiceDep / StorageServiceDep;DailyBudgetGuard 接收 tiers - uv add cos-python-sdk-v5;import-linter/CI/Makefile 纳入两个新包