Files
social-app/docs/plans/2026-02-24-auth-profile-implementation.md
T

137 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 Authsignup/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 更新成功