upd
This commit is contained in:
27
CLAUDE.md
27
CLAUDE.md
@@ -23,6 +23,31 @@
|
||||
|
||||
---
|
||||
|
||||
## Рефакторинг: мульти-профиль (02.06.2026)
|
||||
|
||||
Полная переработка доменной модели. Основная причина: один пользователь
|
||||
может иметь несколько публичных профилей. Все социальные операции
|
||||
переведены с `user_id` на `profile_id`.
|
||||
|
||||
**Ключевые изменения схемы:**
|
||||
- `profile.user_id` — убран `UNIQUE`, теперь один user → много профилей
|
||||
- `profile.active_chat_id` — перенесено из `user` в `profile`
|
||||
- `user.active_chat_id` — удалено
|
||||
- `media` → `profile_media` (FK на `profile`, тип: `photo | video | audio`, добавлен `sort_order`)
|
||||
- `like.source_user/target_user` → `like.source_profile_id/target_profile_id`
|
||||
- `match.user1_id/user2_id` → `match.profile1_id/profile2_id`
|
||||
- `chat.profile1_id/profile2_id` — теперь честные FK на `profile`
|
||||
- `message.user_id` → `message.profile_id`
|
||||
- `date.user1_id/user2_id` → `date.profile1_id/profile2_id`
|
||||
- `report.source_user` → `report.source_profile_id`
|
||||
|
||||
**Паттерн ownership:** все операции, изменяющие профиль, проверяют
|
||||
`profile.user_id === jwt.sub` через `assertProfileOwnership()` в каждом сервисе.
|
||||
|
||||
**WebSocket:** `profileId` передаётся в `handshake.auth.profileId` при подключении.
|
||||
|
||||
---
|
||||
|
||||
## Архитектурные решения
|
||||
|
||||
### 1. Глобальный JWT-guard через `APP_GUARD`
|
||||
@@ -103,7 +128,7 @@ seed (например, хешем userId + дата).
|
||||
|
||||
| # | Пункт ТЗ | Как реализовано | Причина |
|
||||
|---|---|---|---|
|
||||
| 1 | `chat.profile1_id → profile` | Поле хранит `user_id` | Матч создаётся между пользователями, а не профилями; JOIN с профилем не нужен на горячем пути |
|
||||
| 1 | `chat.profile1_id → profile` | Реализовано корректно после рефакторинга | — |
|
||||
| 2 | Поиск «неактивен» при превышении лимита матчей | `BadRequestException` при лайке | Проще контракт с клиентом: ошибка явная, не нужно отдельного флага `searchActive` |
|
||||
| 3 | Тарифный план один, но оплата предусмотрена | Таблицы `tariff` и `payment` созданы, логика оплаты не реализована | ТЗ: «регистрация открыта для всех, тарифный план один» — бизнес-логики оплаты нет |
|
||||
| 4 | `radiusKm` в фильтре ленты | Параметр принимается, но фильтрация по радиусу не применяется | Требует PostGIS или формулы Haversine; добавить в следующей итерации |
|
||||
|
||||
Reference in New Issue
Block a user