chore(openspec): archive add-user-profile and sync main specs

This commit is contained in:
iu
2026-10-12 14:27:19 +03:00
parent 86aff695df
commit 657a04309e
8 changed files with 139 additions and 7 deletions
@@ -0,0 +1,51 @@
# Tasks
## 1. Модель данных и миграции
- [x] 1.1 Добавить `Phone` в `models.User` (но НЕ в `PublicUser`) — unit-тест: JSON `PublicUser` не содержит телефон
- [x] 1.2 Миграция PostgreSQL `000013_user_phone` (снять `NOT NULL` с email, добавить `phone` + unique, down-миграция) — проверить `make migrate` и откат на чистой БД
- [x] 1.3 Миграция SQLite `000005_user_phone` через rebuild `users` — проверить на копии `galo.db`, что данные сохранены, email nullable, `phone` присутствует
- [x] 1.4 Расширить миграционный тест `internal/e2e` — проверка схемы `users` (nullable email, колонка `phone`, уникальность)
## 2. Backend: вход и регистрация по идентификатору
- [x] 2.1 Нормализация E.164 и определение типа идентификатора (`@` → email) — unit-тест на валидные/невалидные номера
- [x] 2.2 Хранилища: `COALESCE(email,'')` в выборках, `GetUserByPhone` в `store.go` и `sqlite_store.go` — тесты обоих хранилищ
- [x] 2.3 `Service.Register` принимает email и/или телефон, требует «хотя бы один», ловит конфликты `email_taken`/`phone_taken` — тесты
- [x] 2.4 `Service.Login` по единому идентификатору — тесты: вход по email, по телефону, несуществующий, неверный пароль (ответ неразличим)
- [x] 2.5 Хендлеры `login` (`identifier`) и `register` (`phone` необязателен) — тесты хендлеров
## 3. Backend: профиль (имя, пароль, добавление идентификатора)
- [x] 3.1 `PATCH /auth/me` для изменения имени (пустое отклоняется) — тесты сервиса и хендлера
- [x] 3.2 `POST /auth/me/password`: проверка текущего пароля, минимум 8 символов, `RevokeAllUserTokens` при успехе — тесты
- [x] 3.3 `POST /auth/me/identifiers` (add-only): добавление недостающего email/phone, конфликты, отказ когда оба заданы — тесты
- [x] 3.4 `/auth/me` отдаёт телефон только владельцу — тест: ответ `Me` содержит phone, публичные представления — нет
## 4. Backend: удаление аккаунта
- [x] 4.1 `DELETE /auth/me` с подтверждением пароля и `DeleteUser` в обоих хранилищах — тесты: неверный пароль, успешное удаление
- [x] 4.2 Интеграционный тест: удаление владельца с общим альбомом убирает альбом у другого участника
## 5. Web-интерфейс
- [x] 5.1 Login/register: единое поле «Email или телефон», необязательные email/phone с проверкой «хотя бы одно»; обновить `api.ts`, `types.ts` — проверить `npm run check` и ручной вход
- [x] 5.2 Новая страница `(app)/profile` (имя, пароль, добавление идентификатора, удаление) и ссылка из шапки `AppShell` — проверить `npm run check` и ручной сценарий
- [x] 5.3 Очистка токенов и редирект на вход после смены пароля и удаления — ручная проверка в браузере
## 6. Android-клиент
- [x] 6.1 DTO/API: login по `identifier`, `phone` при регистрации, эндпоинты профиля; обновить `ErrorMapper` — unit-тест маппинга ошибок
- [x] 6.2 `AuthScreen`: единое поле идентификатора, необязательные email/phone — Robolectric-тест
- [x] 6.3 `ProfileScreen` + `ProfileViewModel` + запись в `GaloNavHost`, вход из списка альбомов — Robolectric-тест
- [x] 6.4 Очистка `TokenStore` и возврат на экран auth после смены пароля/удаления — Robolectric-тест
## 7. Интеграция и документация
- [x] 7.1 E2E против запущенного сервера: регистрация только по телефону, вход, добавление email, смена пароля (сессии отозваны), удаление аккаунта
- [x] 7.2 `scripts/seed.py`: поддержать необязательный `phone`; обновить README (новые эндпоинты профиля) — проверить запуск `make testdata` и чтение README
- [ ] 7.3 Полный прогон: `make test`, `cd frontend && npm run check`, `cd android && ./gradlew test`
## Workflow follow-up
- Архивировать изменение после прохождения ревью и синхронизировать основные спеки.