feat(invites): приглашения, каталог публичных серверов и публичность сервера
- POST /guilds/{id}/invites (CREATE_INVITES): код из 10 символов, лимит
использований и срок жизни; GET /guilds/{id}/invites (MANAGE_GUILD);
DELETE /invites/{code} — создатель или MANAGE_GUILD;
- GET /invites/{code} — предпросмотр с карточкой сервера, 410 для истёкших и
исчерпанных; POST /invites/{code} — принятие с проверкой лимита участников,
повторное принятие не расходует использование;
- PATCH /guilds/{id} принимает `public`: сервер попадает в каталог и открыт для
входа без приглашения (главный сервер публиковать нельзя);
- GET /guilds/public — каталог (имя, описание, иконка, число участников);
- аудит invite.create/invite.revoke/invite.accept, события INVITE_CREATE и
INVITE_DELETE владельцу сессии;
- тесты: полный жизненный цикл приглашения, исчерпание, отзыв, права,
публичный каталог и вход в публичный сервер.
This commit is contained in:
@@ -221,6 +221,9 @@ func (s *Server) registerGuildCoreRoutes(api huma.API) {
|
||||
Body struct {
|
||||
Name *string `json:"name,omitempty" maxLength:"64"`
|
||||
Description *string `json:"description,omitempty" maxLength:"500"`
|
||||
// Публичность сервера: попадает в каталог и открывает вход без
|
||||
// приглашения (AGENT.md 7.20).
|
||||
Public *bool `json:"public,omitempty"`
|
||||
}
|
||||
},
|
||||
) (*guildOutput, error) {
|
||||
@@ -233,6 +236,19 @@ func (s *Server) registerGuildCoreRoutes(api huma.API) {
|
||||
return nil, err
|
||||
}
|
||||
params := store.UpdateGuildParams{Description: input.Body.Description}
|
||||
if input.Body.Public != nil {
|
||||
// Главный сервер публичным не делаем: он и так точка входа.
|
||||
if *input.Body.Public {
|
||||
guild, err := s.store.GetGuild(ctx, guildID)
|
||||
if err != nil {
|
||||
return nil, humaError(err)
|
||||
}
|
||||
if guild.IsMain {
|
||||
return nil, humaErrorStatus(http.StatusUnprocessableEntity, "validation.failed", "main guild is always open and cannot be published")
|
||||
}
|
||||
}
|
||||
params.IsDiscoverable = input.Body.Public
|
||||
}
|
||||
if input.Body.Name != nil {
|
||||
trimmed := strings.TrimSpace(*input.Body.Name)
|
||||
if trimmed == "" {
|
||||
|
||||
Reference in New Issue
Block a user