# ECR-015 **Title:** 账号头像上传与媒体读取 **Status:** Approved **Date:** 2026-08-13 **Approved:** 2026-08-13(Human:开 Architect · 头像另 Context) **Change Level:** L2 **Retrospective:** true ## Retro(异常路径) | Field | Content | |-------|---------| | Original drift | Spec `account-auth` R9 与 FE「我的」页、migration `000018`、handler/media/avatar 已先于本 ECR 进树 | | Scope freeze | 仅头像上传/存储/读取与 `avatar_url` 契约;禁止顺手改昵称规则、登录开放策略、Ops | | Process debt | 倒序实现;CODE_REVIEW 须点名;不得伪装正序路径 | ## Change 1. 对齐 Spec `account-auth.md` R9 · §8–§10 2. 后台:`users.avatar_url` · `POST /auth/me/avatar` · `GET /media/avatars/:file` · 本地 `data/avatars/` 3. H5:「我的」更换头像(相册/拍照);默认 `public/default-avatar.png` 4. SDK `authUploadAvatar` · types `avatar_url` · OpenAPI 5. 单测(类型/大小校验)+ 冒烟清单 ## Motivation 账号展示位需要可换头像;与昵称同属账号资产。 ## Scope ### Allowed - migration `000018_user_avatar` - `internal/avatar` · `handler` UploadAvatar / MediaHandler - `service/auth` UpdateAvatar · auth_repo avatar 字段 - H5 MinePage 头像 UI · `defaultAvatar` / `apiAsset`(若缺则补) - `packages/sdk` · `packages/types` · `proto/openapi.yaml` 头像相关 - Spec account-auth R9;TEST / HANDOFF ### Forbidden - 改 R1 OpenLogin 策略 · textsafe 规则扩 scope · scalebank · 时效刷新(ECR-014)· Admin · 对象存储/CDN 上云(可后 ECR) ## Acceptance - [x] 已登录 POST multipart jpeg/png/webp ≤2MB → 200 · `avatar_url` 非空 - [x] 超限/错误类型 → 4xx 可读文案 - [x] GET `/media/avatars/:file` 可公开读已存文件;路径穿越拒绝 - [x] GET `/auth/me` 含 `avatar_url`;未设置时 H5 显示默认愈心小人 - [x] OpenAPI 覆盖 upload + media - [x] go test avatar PASS;ess-validate coding PASS - [x] CODE_REVIEW 记 Retro(Reviewer) ## Trace Spec `account-auth` · TASK-015 · BD-2026-015 · TEST_REPORT/ECR-015.md