Skip to content

[Feature] Реализация управления приглашениями (Invitations CRUD) #21

@soorq

Description

@soorq

Контекст

В текущем контроллере TeamsInvitationsController методы getAll, getOne, update и decline помечены как @Deprecated. Нам нужно реализовать их полноценную работу, убрав статус deprecated и обеспечив корректную логику обработки данных.

Цель

Реализовать полноценный RESTful-интерфейс для управления приглашениями в команде.


Технические требования

  1. Локация логики: Весь код должен жить в InvationsService.
  2. Структура данных:
    • Инвайты хранятся как inv:code:{code} (JSON).
    • Индексы (для быстрого поиска): team:invites:{teamId} (Set) и user:invites:{email} (Set).
  3. Безопасность: Можешь реализовать гвард - TeamOwnerGuard, пока лучше просто проверять, что данный пользователь, через декоратор @GetUserId() полученный - имеет доступ к инвайтам в эту команду.

1. Реализация GET /teams/:slug/invitations

  • Сервис: getInvitations(slug: string).
  • Логика:
    1. Найти team.id по slug.
    2. Получить список всех кодов через SMEMBERS team:invites:{teamId}.
    3. Выбрать данные через MGET по списку ключей inv:code:{code}.
    4. Отфильтровать null значения (если Redis протух, а индекс остался — это "мусор", его нужно игнорировать).

2. Реализация GET /teams/:slug/invitations/:code

  • Сервис: getInvitation(code: string).
  • Логика: GET из Redis по ключу inv:code:{code}.

3. Реализация PATCH /teams/:slug/invitations/:code

  • DTO: UpdateInvitationDto (разрешить только поле role).
  • Логика:
    1. Получить текущий объект invitation из Redis.
    2. Обновить поле role.
    3. Сохранить обратно с тем же TTL (используй TTL ключа, чтобы не сбросить время жизни).

4. Реализация DELETE /teams/:slug/invitations/:code

  • Сервис: removeInvitation(teamId: string, code: string, email: string).
  • Логика: Используй MULTI/EXEC для атомарного удаления:
    1. DEL inv:code:{code}
    2. SREM team:invites:{teamId} {code}
    3. SREM user:invites:{email} {code}

Важные указания для джуна

  • Атомарность: Все операции записи/удаления инвайтов должны выполняться через MULTI/EXEC, чтобы индексы не рассинхронизировались с данными.
  • Ошибка 404: Если MGET вернул пустой массив или GET вернул null — выбрасывай NotFoundException.
  • Семантика: В путях используй :code (уникальный ключ приглашения), а не :invitationId, так как мы работаем с Redis-ключами по коду.

Если возникнут вопросы по работе с SREM или SMEMBERS — читай документацию ioredis или спрашивай меня в комментариях к тикету.

Metadata

Metadata

Assignees

Labels

api-designEndpoint and CRUD'sdocumentationImprovements or additions to documentationenhancementNew feature or request

Type

No fields configured for Task.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions