feat(templates): личные шаблоны серверов в хранилище и API (Фаза 7)
AGENT.md 7.3: свои шаблоны серверов — сохранить структуру сервера
(роли с правами и цветом, категории и комнаты) и создать по ней новый.
Миграция 00023 создаёт guild_templates (structure_json, source_guild_id,
каскад по владельцу) с индексом владельца.
- store: CRUD личных шаблонов с фильтром по owner_id и защитой лимитов
(20 шаблонов, 16 КиБ structure_json);
- server: POST /guild-templates, GET /guild-templates/mine и
DELETE /guild-templates/{id} (MANAGE_GUILD, чужой шаблон — 404),
создание сервера по template_id=personal:<id> (аудит template=personal:<id>);
- структура шаблона повторяет API ролей (права строкой) и хранит
slowmode_seconds, user_limit и категорию по имени.
This commit is contained in:
@@ -271,6 +271,9 @@ func (s *Server) registerGuildCoreRoutes(api huma.API) {
|
||||
return output, nil
|
||||
})
|
||||
|
||||
// Личные шаблоны серверов (Фаза 7): сохранить структуру, список и удаление.
|
||||
s.registerUserGuildTemplateRoutes(api, security)
|
||||
|
||||
huma.Register(api, huma.Operation{
|
||||
OperationID: "getGuild",
|
||||
Method: http.MethodGet,
|
||||
@@ -1812,11 +1815,12 @@ func (s *Server) recordAudit(ctx context.Context, actor *store.User, guildID uin
|
||||
}
|
||||
}
|
||||
|
||||
// createGuild создаёт сервер с ролями по умолчанию и общей комнатой (AGENT.md 6.3).
|
||||
// createGuild создаёт сервер с ролями по умолчанию и структурой выбранного
|
||||
// шаблона — встроенного или личного (AGENT.md 6.3, 7.3).
|
||||
func (s *Server) createGuild(ctx context.Context, owner *store.User, name, templateID string) (*store.Guild, error) {
|
||||
template, known := findGuildTemplate(templateID)
|
||||
if !known {
|
||||
return nil, humaErrorStatus(http.StatusUnprocessableEntity, "validation.failed", "unknown guild template")
|
||||
template, templateReason, err := s.resolveGuildTemplate(ctx, owner, templateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
settings, err := s.store.InstanceSettings(ctx)
|
||||
if err != nil {
|
||||
@@ -1860,7 +1864,8 @@ func (s *Server) createGuild(ctx context.Context, owner *store.User, name, templ
|
||||
return nil, humaError(err)
|
||||
}
|
||||
}
|
||||
s.recordAudit(ctx, owner, guild.ID, "guild.create", "guild", &guild.ID, "template="+template.ID)
|
||||
// Причина аудита: встроенный шаблон или personal:<id> у личного (7.3).
|
||||
s.recordAudit(ctx, owner, guild.ID, "guild.create", "guild", &guild.ID, templateReason)
|
||||
if bypassed {
|
||||
s.recordAudit(ctx, owner, guild.ID, "limits.bypass", "guild", &guild.ID, "instance admin bypassed guild limit")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user