# Auth Profile Enhancement Implementation Plan

> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.

**Goal:** 基于 Supabase 能力补齐注册/登录/按邮箱查用户/更新 profile 的一致化实现，并移除 profiles.display_name。

**Architecture:** 认证流程继续走 Supabase Auth（signup/login/refresh/logout），后端仅做薄封装与输入校验。profiles 通过 auth.users 触发器自动创建并绑定同一 id，profile 资料更新仍走业务接口。新增按邮箱查用户接口走 service_role 的 Admin API。

**Tech Stack:** FastAPI, Supabase Python SDK, SQLAlchemy, Alembic, PostgreSQL

---

### Task 1: 调整 profiles 数据模型与迁移

**Files:**
- Modify: `backend/src/models/profile.py`
- Create: `backend/alembic/versions/20260224_drop_profile_display_name_and_trigger_username.py`

**Step 1: Write the failing test**

- 新增迁移验证脚本测试：断言 `profiles` 不含 `display_name` 且触发器使用 metadata.username。

**Step 2: Run test to verify it fails**

Run: `PYTHONPATH=src uv run python -m pytest tests/integration -k profile_migration -q`
Expected: FAIL（旧结构仍有 display_name 或触发器逻辑不匹配）

**Step 3: Write minimal implementation**

- model 删除 `display_name`
- 迁移删除列并重建触发器函数：`profiles.username = NEW.raw_user_meta_data->>'username'`

**Step 4: Run test to verify it passes**

Run: `PYTHONPATH=src uv run python -m pytest tests/integration -k profile_migration -q`
Expected: PASS

### Task 2: 注册接口改为 username+email+password

**Files:**
- Modify: `backend/src/v1/auth/schemas.py`
- Modify: `backend/src/v1/auth/service.py`

**Step 1: Write the failing test**

- 测试 signup 缺 username 返回 422
- 测试 signup 将 `data.username` 传递给 Supabase gateway

**Step 2: Run test to verify it fails**

Run: `PYTHONPATH=src uv run python -m pytest tests/unit -k auth_signup -q`
Expected: FAIL

**Step 3: Write minimal implementation**

- `SignupRequest` 添加必填 `username`
- `SupabaseAuthGateway.signup` payload 增加 `data.username`

**Step 4: Run test to verify it passes**

Run: `PYTHONPATH=src uv run python -m pytest tests/unit -k auth_signup -q`
Expected: PASS

### Task 3: 新增按邮箱查询 auth 用户接口

**Files:**
- Modify: `backend/src/v1/auth/router.py`
- Modify: `backend/src/v1/auth/service.py`
- Modify: `backend/src/v1/auth/schemas.py`

**Step 1: Write the failing test**

- 测试 `GET /auth/users/by-email` 命中返回用户最小字段
- 测试未命中返回 404

**Step 2: Run test to verify it fails**

Run: `PYTHONPATH=src uv run python -m pytest tests/unit -k auth_by_email -q`
Expected: FAIL

**Step 3: Write minimal implementation**

- service 新增 `get_user_by_email`
- gateway 用 service_role client 调用 Supabase Admin 查询
- router 暴露 `GET /auth/users/by-email`

**Step 4: Run test to verify it passes**

Run: `PYTHONPATH=src uv run python -m pytest tests/unit -k auth_by_email -q`
Expected: PASS

### Task 4: profile 更新协议去除 display_name

**Files:**
- Modify: `backend/src/v1/profile/schemas.py`
- Modify: `backend/src/v1/profile/service.py`
- Modify: `backend/src/v1/profile/router.py`

**Step 1: Write the failing test**

- 测试 `PATCH /profile/me` 仅允许 `username/avatar_url/bio`

**Step 2: Run test to verify it fails**

Run: `PYTHONPATH=src uv run python -m pytest tests/unit -k profile_update -q`
Expected: FAIL

**Step 3: Write minimal implementation**

- 移除 display_name 字段与映射
- 保留原有更新路径和事务边界

**Step 4: Run test to verify it passes**

Run: `PYTHONPATH=src uv run python -m pytest tests/unit -k profile_update -q`
Expected: PASS

### Task 5: 集成验证

**Files:**
- Modify: `docs/runtime/runtime-runbook.md`

**Step 1: 运行关键验证**

Run: `docker compose --env-file .env -f infra/docker/docker-compose.yml --profile job run --rm init-job`
Expected: 迁移成功

Run: `PYTHONPATH=src uv run python -m pytest tests -q`
Expected: 全部通过

**Step 2: 手工 API 验证**

- signup(username,email,password) 成功
- login(email,password) 成功
- by-email 查询命中
- patch profile 更新成功
